@memberjunction/ng-conversations 2.128.0 → 2.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/lib/components/attachment/image-viewer.component.d.ts +95 -0
  2. package/dist/lib/components/attachment/image-viewer.component.d.ts.map +1 -0
  3. package/dist/lib/components/attachment/image-viewer.component.js +293 -0
  4. package/dist/lib/components/attachment/image-viewer.component.js.map +1 -0
  5. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +88 -26
  6. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  7. package/dist/lib/components/conversation/conversation-chat-area.component.js +542 -338
  8. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts +12 -3
  10. package/dist/lib/components/conversation/conversation-empty-state.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-empty-state.component.js +68 -55
  12. package/dist/lib/components/conversation/conversation-empty-state.component.js.map +1 -1
  13. package/dist/lib/components/conversation/conversation-list.component.d.ts +13 -1
  14. package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -1
  15. package/dist/lib/components/conversation/conversation-list.component.js +237 -119
  16. package/dist/lib/components/conversation/conversation-list.component.js.map +1 -1
  17. package/dist/lib/components/mention/mention-editor.component.d.ts +102 -5
  18. package/dist/lib/components/mention/mention-editor.component.d.ts.map +1 -1
  19. package/dist/lib/components/mention/mention-editor.component.js +349 -21
  20. package/dist/lib/components/mention/mention-editor.component.js.map +1 -1
  21. package/dist/lib/components/message/agent-response-form.component.d.ts +18 -0
  22. package/dist/lib/components/message/agent-response-form.component.d.ts.map +1 -1
  23. package/dist/lib/components/message/agent-response-form.component.js +149 -26
  24. package/dist/lib/components/message/agent-response-form.component.js.map +1 -1
  25. package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
  26. package/dist/lib/components/message/conversation-message-rating.component.js +3 -2
  27. package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
  28. package/dist/lib/components/message/form-question.component.js +3 -3
  29. package/dist/lib/components/message/message-input-box.component.d.ts +29 -2
  30. package/dist/lib/components/message/message-input-box.component.d.ts.map +1 -1
  31. package/dist/lib/components/message/message-input-box.component.js +79 -12
  32. package/dist/lib/components/message/message-input-box.component.js.map +1 -1
  33. package/dist/lib/components/message/message-input.component.d.ts +60 -5
  34. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  35. package/dist/lib/components/message/message-input.component.js +303 -119
  36. package/dist/lib/components/message/message-input.component.js.map +1 -1
  37. package/dist/lib/components/message/message-item.component.d.ts +41 -3
  38. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  39. package/dist/lib/components/message/message-item.component.js +237 -106
  40. package/dist/lib/components/message/message-item.component.js.map +1 -1
  41. package/dist/lib/components/message/message-list.component.d.ts +7 -2
  42. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  43. package/dist/lib/components/message/message-list.component.js +19 -4
  44. package/dist/lib/components/message/message-list.component.js.map +1 -1
  45. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +7 -1
  46. package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -1
  47. package/dist/lib/components/sidebar/conversation-sidebar.component.js +28 -6
  48. package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -1
  49. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +83 -10
  50. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  51. package/dist/lib/components/workspace/conversation-workspace.component.js +290 -103
  52. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  53. package/dist/lib/conversations.module.d.ts +26 -25
  54. package/dist/lib/conversations.module.d.ts.map +1 -1
  55. package/dist/lib/conversations.module.js +7 -3
  56. package/dist/lib/conversations.module.js.map +1 -1
  57. package/dist/lib/models/conversation-state.model.d.ts +2 -1
  58. package/dist/lib/models/conversation-state.model.d.ts.map +1 -1
  59. package/dist/lib/services/active-tasks.service.d.ts +23 -0
  60. package/dist/lib/services/active-tasks.service.d.ts.map +1 -1
  61. package/dist/lib/services/active-tasks.service.js +91 -2
  62. package/dist/lib/services/active-tasks.service.js.map +1 -1
  63. package/dist/lib/services/agent-state.service.d.ts +2 -0
  64. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  65. package/dist/lib/services/agent-state.service.js +20 -3
  66. package/dist/lib/services/agent-state.service.js.map +1 -1
  67. package/dist/lib/services/conversation-agent.service.d.ts +38 -6
  68. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  69. package/dist/lib/services/conversation-agent.service.js +233 -71
  70. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  71. package/dist/lib/services/conversation-attachment.service.d.ts +79 -0
  72. package/dist/lib/services/conversation-attachment.service.d.ts.map +1 -0
  73. package/dist/lib/services/conversation-attachment.service.js +327 -0
  74. package/dist/lib/services/conversation-attachment.service.js.map +1 -0
  75. package/dist/lib/services/conversation-data.service.d.ts +15 -1
  76. package/dist/lib/services/conversation-data.service.d.ts.map +1 -1
  77. package/dist/lib/services/conversation-data.service.js +23 -1
  78. package/dist/lib/services/conversation-data.service.js.map +1 -1
  79. package/dist/lib/services/conversation-streaming.service.d.ts +50 -1
  80. package/dist/lib/services/conversation-streaming.service.d.ts.map +1 -1
  81. package/dist/lib/services/conversation-streaming.service.js +92 -4
  82. package/dist/lib/services/conversation-streaming.service.js.map +1 -1
  83. package/dist/lib/services/mention-autocomplete.service.d.ts +1 -1
  84. package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -1
  85. package/dist/lib/services/mention-parser.service.d.ts +16 -1
  86. package/dist/lib/services/mention-parser.service.d.ts.map +1 -1
  87. package/dist/lib/services/mention-parser.service.js +30 -0
  88. package/dist/lib/services/mention-parser.service.js.map +1 -1
  89. package/dist/public-api.d.ts +2 -0
  90. package/dist/public-api.d.ts.map +1 -1
  91. package/dist/public-api.js +2 -0
  92. package/dist/public-api.js.map +1 -1
  93. package/package.json +17 -17
@@ -1,10 +1,12 @@
1
1
  import { Component, Input, Output, EventEmitter, ViewChild, ViewChildren } from '@angular/core';
2
2
  import { RunView, RunQuery, Metadata, CompositeKey, LogStatusEx } from '@memberjunction/core';
3
+ import { AIEngineBase } from '@memberjunction/ai-engine-base';
3
4
  import { LazyArtifactInfo } from '../../models/lazy-artifact-info';
4
5
  import { parseConversationDetailComplete } from '../../models/conversation-complete-query.model';
5
6
  import { ArtifactViewerPanelComponent } from '@memberjunction/ng-artifacts';
6
7
  import { TestFeedbackDialogComponent } from '@memberjunction/ng-testing';
7
8
  import { Subject } from 'rxjs';
9
+ import { takeUntil } from 'rxjs/operators';
8
10
  import * as i0 from "@angular/core";
9
11
  import * as i1 from "../../services/conversation-data.service";
10
12
  import * as i2 from "../../services/agent-state.service";
@@ -13,30 +15,40 @@ import * as i4 from "../../services/active-tasks.service";
13
15
  import * as i5 from "../../services/mention-autocomplete.service";
14
16
  import * as i6 from "../../services/artifact-permission.service";
15
17
  import * as i7 from "@progress/kendo-angular-dialog";
16
- import * as i8 from "@angular/common";
17
- import * as i9 from "@memberjunction/ng-artifacts";
18
- import * as i10 from "@memberjunction/ng-shared-generic";
19
- import * as i11 from "../collection/artifact-collection-picker-modal.component";
20
- import * as i12 from "../artifact/artifact-share-modal.component";
21
- import * as i13 from "../message/message-list.component";
22
- import * as i14 from "../message/message-input.component";
23
- import * as i15 from "./conversation-empty-state.component";
24
- import * as i16 from "../thread/thread-panel.component";
25
- import * as i17 from "../project/project-selector.component";
26
- import * as i18 from "../agent/active-agent-indicator.component";
27
- import * as i19 from "../members/members-modal.component";
28
- import * as i20 from "../export/export-modal.component";
18
+ import * as i8 from "../../services/conversation-attachment.service";
19
+ import * as i9 from "../../services/conversation-streaming.service";
20
+ import * as i10 from "@angular/common";
21
+ import * as i11 from "@memberjunction/ng-artifacts";
22
+ import * as i12 from "@memberjunction/ng-shared-generic";
23
+ import * as i13 from "../collection/artifact-collection-picker-modal.component";
24
+ import * as i14 from "../artifact/artifact-share-modal.component";
25
+ import * as i15 from "../message/message-list.component";
26
+ import * as i16 from "../message/message-input.component";
27
+ import * as i17 from "./conversation-empty-state.component";
28
+ import * as i18 from "../thread/thread-panel.component";
29
+ import * as i19 from "../project/project-selector.component";
30
+ import * as i20 from "../agent/active-agent-indicator.component";
31
+ import * as i21 from "../members/members-modal.component";
32
+ import * as i22 from "../export/export-modal.component";
33
+ import * as i23 from "../attachment/image-viewer.component";
29
34
  const _c0 = ["scrollContainer"];
30
35
  const _c1 = ["messageInput"];
31
36
  const _forTrack0 = ($index, $item) => $item.conversationId;
32
37
  const _forTrack1 = ($index, $item) => $item.artifactId;
33
38
  const _forTrack2 = ($index, $item) => $item.versionId;
34
39
  const _c2 = () => [];
35
- function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf & 1) {
40
+ function ConversationChatAreaComponent_div_1_button_2_Template(rf, ctx) { if (rf & 1) {
36
41
  const _r2 = i0.ɵɵgetCurrentView();
37
- i0.ɵɵelementStart(0, "button", 30);
38
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openProjectSelector()); });
39
- i0.ɵɵelement(1, "i", 31);
42
+ i0.ɵɵelementStart(0, "button", 32);
43
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.sidebarToggleClicked.emit()); });
44
+ i0.ɵɵelement(1, "i", 33);
45
+ i0.ɵɵelementEnd();
46
+ } }
47
+ function ConversationChatAreaComponent_div_1_button_5_Template(rf, ctx) { if (rf & 1) {
48
+ const _r4 = i0.ɵɵgetCurrentView();
49
+ i0.ɵɵelementStart(0, "button", 34);
50
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openProjectSelector()); });
51
+ i0.ɵɵelement(1, "i", 35);
40
52
  i0.ɵɵelementStart(2, "span");
41
53
  i0.ɵɵtext(3);
42
54
  i0.ɵɵelementEnd()();
@@ -45,60 +57,76 @@ function ConversationChatAreaComponent_div_1_button_4_Template(rf, ctx) { if (rf
45
57
  i0.ɵɵadvance(3);
46
58
  i0.ɵɵtextInterpolate(ctx_r2.conversation.Project || "Project");
47
59
  } }
48
- function ConversationChatAreaComponent_div_1_button_5_Template(rf, ctx) { if (rf & 1) {
49
- const _r4 = i0.ɵɵgetCurrentView();
50
- i0.ɵɵelementStart(0, "button", 32);
51
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewTestRun(ctx_r2.conversation.TestRunID)); });
52
- i0.ɵɵelement(1, "i", 33);
60
+ function ConversationChatAreaComponent_div_1_button_6_Template(rf, ctx) { if (rf & 1) {
61
+ const _r5 = i0.ɵɵgetCurrentView();
62
+ i0.ɵɵelementStart(0, "button", 36);
63
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewTestRun(ctx_r2.conversation.TestRunID)); });
64
+ i0.ɵɵelement(1, "i", 37);
53
65
  i0.ɵɵelementStart(2, "span");
54
66
  i0.ɵɵtext(3, "Test");
55
67
  i0.ɵɵelementEnd()();
56
68
  } }
57
- function ConversationChatAreaComponent_div_1_button_12_Template(rf, ctx) { if (rf & 1) {
58
- const _r5 = i0.ɵɵgetCurrentView();
59
- i0.ɵɵelementStart(0, "button", 34);
60
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewArtifacts()); });
61
- i0.ɵɵelement(1, "i", 35);
62
- i0.ɵɵelementStart(2, "span");
69
+ function ConversationChatAreaComponent_div_1_button_9_Template(rf, ctx) { if (rf & 1) {
70
+ const _r6 = i0.ɵɵgetCurrentView();
71
+ i0.ɵɵelementStart(0, "button", 38);
72
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.viewArtifacts()); });
73
+ i0.ɵɵelement(1, "i", 39);
74
+ i0.ɵɵelementStart(2, "span", 40);
63
75
  i0.ɵɵtext(3);
64
76
  i0.ɵɵelementEnd()();
65
77
  } if (rf & 2) {
66
78
  const ctx_r2 = i0.ɵɵnextContext(2);
67
79
  i0.ɵɵadvance(3);
68
- i0.ɵɵtextInterpolate2("", ctx_r2.artifactCountDisplay, " artifact", ctx_r2.artifactCountDisplay !== 1 ? "s" : "", "");
80
+ i0.ɵɵtextInterpolate(ctx_r2.artifactCountDisplay);
81
+ } }
82
+ function ConversationChatAreaComponent_div_1_button_10_Template(rf, ctx) { if (rf & 1) {
83
+ const _r7 = i0.ɵɵgetCurrentView();
84
+ i0.ɵɵelementStart(0, "button", 41);
85
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_button_10_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleMembersModal()); });
86
+ i0.ɵɵelement(1, "i", 42);
87
+ i0.ɵɵelementStart(2, "span", 43);
88
+ i0.ɵɵtext(3);
89
+ i0.ɵɵelementEnd()();
90
+ } if (rf & 2) {
91
+ const ctx_r2 = i0.ɵɵnextContext(2);
92
+ i0.ɵɵadvance(3);
93
+ i0.ɵɵtextInterpolate(ctx_r2.memberCount);
69
94
  } }
70
95
  function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
71
96
  const _r1 = i0.ɵɵgetCurrentView();
72
- i0.ɵɵelementStart(0, "div", 16)(1, "div", 17)(2, "div", 18);
73
- i0.ɵɵtext(3);
97
+ i0.ɵɵelementStart(0, "div", 17)(1, "div", 18);
98
+ i0.ɵɵtemplate(2, ConversationChatAreaComponent_div_1_button_2_Template, 2, 0, "button", 19);
99
+ i0.ɵɵelementStart(3, "div", 20);
100
+ i0.ɵɵtext(4);
74
101
  i0.ɵɵelementEnd();
75
- i0.ɵɵtemplate(4, ConversationChatAreaComponent_div_1_button_4_Template, 4, 1, "button", 19)(5, ConversationChatAreaComponent_div_1_button_5_Template, 4, 0, "button", 20);
76
- i0.ɵɵelementStart(6, "mj-active-agent-indicator", 21);
77
- i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_6_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_6_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgentSelected($event)); });
102
+ i0.ɵɵtemplate(5, ConversationChatAreaComponent_div_1_button_5_Template, 4, 1, "button", 21)(6, ConversationChatAreaComponent_div_1_button_6_Template, 4, 0, "button", 22);
103
+ i0.ɵɵelementStart(7, "mj-active-agent-indicator", 23);
104
+ i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_7_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_7_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgentSelected($event)); });
78
105
  i0.ɵɵelementEnd()();
79
- i0.ɵɵelementStart(7, "div", 22)(8, "button", 23);
80
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleMembersModal()); });
81
- i0.ɵɵelement(9, "i", 24);
82
- i0.ɵɵelementStart(10, "span");
83
- i0.ɵɵtext(11);
106
+ i0.ɵɵelementStart(8, "div", 24);
107
+ i0.ɵɵtemplate(9, ConversationChatAreaComponent_div_1_button_9_Template, 4, 1, "button", 25)(10, ConversationChatAreaComponent_div_1_button_10_Template, 4, 1, "button", 26);
108
+ i0.ɵɵelementStart(11, "button", 27);
109
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.exportConversation()); });
110
+ i0.ɵɵelement(12, "i", 28);
111
+ i0.ɵɵelementStart(13, "span", 29);
112
+ i0.ɵɵtext(14, "Export");
84
113
  i0.ɵɵelementEnd()();
85
- i0.ɵɵtemplate(12, ConversationChatAreaComponent_div_1_button_12_Template, 4, 2, "button", 25);
86
- i0.ɵɵelementStart(13, "mj-active-agent-indicator", 21);
87
- i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_13_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_13_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgentSelected($event)); });
114
+ i0.ɵɵelementStart(15, "button", 30);
115
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.shareConversation()); });
116
+ i0.ɵɵelement(16, "i", 31);
117
+ i0.ɵɵelementStart(17, "span", 29);
118
+ i0.ɵɵtext(18, "Share");
88
119
  i0.ɵɵelementEnd()();
89
- i0.ɵɵelementStart(14, "div", 22)(15, "button", 26);
90
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.exportConversation()); });
91
- i0.ɵɵelement(16, "i", 27);
92
- i0.ɵɵtext(17, " Export ");
93
- i0.ɵɵelementEnd();
94
- i0.ɵɵelementStart(18, "button", 28);
95
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_div_1_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.shareConversation()); });
96
- i0.ɵɵelement(19, "i", 29);
97
- i0.ɵɵtext(20, " Share ");
120
+ i0.ɵɵelementStart(19, "mj-active-agent-indicator", 23);
121
+ i0.ɵɵlistener("togglePanel", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_togglePanel_19_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onToggleAgentPanel()); })("agentSelected", function ConversationChatAreaComponent_div_1_Template_mj_active_agent_indicator_agentSelected_19_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAgentSelected($event)); });
98
122
  i0.ɵɵelementEnd()()();
99
123
  } if (rf & 2) {
100
124
  const ctx_r2 = i0.ɵɵnextContext();
101
- i0.ɵɵadvance(3);
125
+ i0.ɵɵadvance();
126
+ i0.ɵɵclassProp("with-sidebar-toggle", ctx_r2.showSidebarToggle);
127
+ i0.ɵɵadvance();
128
+ i0.ɵɵproperty("ngIf", ctx_r2.showSidebarToggle);
129
+ i0.ɵɵadvance(2);
102
130
  i0.ɵɵtextInterpolate(ctx_r2.conversation.Name);
103
131
  i0.ɵɵadvance();
104
132
  i0.ɵɵproperty("ngIf", ctx_r2.conversation.ProjectID);
@@ -106,55 +134,64 @@ function ConversationChatAreaComponent_div_1_Template(rf, ctx) { if (rf & 1) {
106
134
  i0.ɵɵproperty("ngIf", ctx_r2.conversation.TestRunID);
107
135
  i0.ɵɵadvance();
108
136
  i0.ɵɵproperty("conversationId", ctx_r2.conversation.ID)("currentUser", ctx_r2.currentUser);
109
- i0.ɵɵadvance(5);
110
- i0.ɵɵtextInterpolate2("", ctx_r2.memberCount, " member", ctx_r2.memberCount !== 1 ? "s" : "", "");
111
- i0.ɵɵadvance();
137
+ i0.ɵɵadvance(2);
112
138
  i0.ɵɵproperty("ngIf", ctx_r2.artifactCountDisplay > 0);
113
139
  i0.ɵɵadvance();
114
- i0.ɵɵproperty("conversationId", ctx_r2.conversation.ID)("currentUser", ctx_r2.currentUser);
140
+ i0.ɵɵproperty("ngIf", ctx_r2.memberCount > 1);
115
141
  i0.ɵɵadvance(5);
116
142
  i0.ɵɵclassProp("shared", ctx_r2.isShared);
117
143
  i0.ɵɵproperty("title", ctx_r2.isShared ? "Manage sharing" : "Share conversation");
144
+ i0.ɵɵadvance(4);
145
+ i0.ɵɵproperty("conversationId", ctx_r2.conversation.ID)("currentUser", ctx_r2.currentUser);
118
146
  } }
119
147
  function ConversationChatAreaComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
120
- const _r6 = i0.ɵɵgetCurrentView();
121
- i0.ɵɵelementStart(0, "mj-conversation-empty-state", 36);
122
- i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEmptyStateMessageSent($event)); });
148
+ const _r8 = i0.ɵɵgetCurrentView();
149
+ i0.ɵɵelementStart(0, "mj-conversation-empty-state", 44);
150
+ i0.ɵɵlistener("sidebarToggleClicked", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_sidebarToggleClicked_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.sidebarToggleClicked.emit()); })("messageSent", function ConversationChatAreaComponent_Conditional_4_Template_mj_conversation_empty_state_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onEmptyStateMessageSent($event)); });
123
151
  i0.ɵɵelementEnd();
124
152
  } if (rf & 2) {
125
153
  const ctx_r2 = i0.ɵɵnextContext();
126
- i0.ɵɵproperty("currentUser", ctx_r2.currentUser)("disabled", ctx_r2.isProcessing);
154
+ i0.ɵɵproperty("currentUser", ctx_r2.currentUser)("disabled", ctx_r2.isProcessing)("showSidebarToggle", ctx_r2.showSidebarToggle);
127
155
  } }
128
156
  function ConversationChatAreaComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
129
157
  i0.ɵɵelementStart(0, "div", 7);
130
- i0.ɵɵelement(1, "mj-loading", 37);
158
+ i0.ɵɵelement(1, "mj-loading", 45);
131
159
  i0.ɵɵelementEnd();
132
160
  } }
133
- function ConversationChatAreaComponent_Conditional_6_span_4_Template(rf, ctx) { if (rf & 1) {
134
- const _r8 = i0.ɵɵgetCurrentView();
135
- i0.ɵɵelementStart(0, "span", 44);
136
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_6_span_4_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.scrollToBottomAnimate()); });
137
- i0.ɵɵelement(1, "i", 45);
161
+ function ConversationChatAreaComponent_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
162
+ i0.ɵɵelementStart(0, "div", 46);
163
+ i0.ɵɵelement(1, "mj-loading", 53);
138
164
  i0.ɵɵelementEnd();
165
+ } if (rf & 2) {
166
+ const ctx_r2 = i0.ɵɵnextContext(2);
167
+ i0.ɵɵadvance();
168
+ i0.ɵɵproperty("text", ctx_r2.uploadingMessage);
139
169
  } }
140
- function ConversationChatAreaComponent_Conditional_6_Conditional_6_Template(rf, ctx) { if (rf & 1) {
141
- i0.ɵɵelementStart(0, "div", 42);
142
- i0.ɵɵelement(1, "mj-loading", 46);
170
+ function ConversationChatAreaComponent_Conditional_6_span_5_Template(rf, ctx) { if (rf & 1) {
171
+ const _r10 = i0.ɵɵgetCurrentView();
172
+ i0.ɵɵelementStart(0, "span", 54);
173
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_6_span_5_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.scrollToBottomAnimate()); });
174
+ i0.ɵɵelement(1, "i", 55);
143
175
  i0.ɵɵelementEnd();
144
176
  } }
145
- function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template(rf, ctx) { if (rf & 1) {
146
- const _r9 = i0.ɵɵgetCurrentView();
147
- i0.ɵɵelementStart(0, "mj-message-input", 48, 1);
148
- i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunDetected($event)); })("agentRunUpdate", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_agentRunUpdate_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunUpdate($event)); })("messageComplete", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_messageComplete_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageComplete($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onConversationRenamed($event)); })("intentCheckStarted", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_intentCheckStarted_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckStarted()); })("intentCheckCompleted", function ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template_mj_message_input_intentCheckCompleted_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckCompleted()); });
177
+ function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
178
+ i0.ɵɵelementStart(0, "div", 51);
179
+ i0.ɵɵelement(1, "mj-loading", 56);
180
+ i0.ɵɵelementEnd();
181
+ } }
182
+ function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
183
+ const _r11 = i0.ɵɵgetCurrentView();
184
+ i0.ɵɵelementStart(0, "mj-message-input", 58, 1);
185
+ i0.ɵɵlistener("messageSent", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_messageSent_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageSent($event)); })("agentResponse", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_agentResponse_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentResponse($event)); })("agentRunDetected", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_agentRunDetected_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunDetected($event)); })("agentRunUpdate", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_agentRunUpdate_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onAgentRunUpdate($event)); })("messageComplete", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_messageComplete_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onMessageComplete($event)); })("artifactCreated", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_artifactCreated_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onArtifactCreated($event)); })("conversationRenamed", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_conversationRenamed_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onConversationRenamed($event)); })("intentCheckStarted", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_intentCheckStarted_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckStarted()); })("intentCheckCompleted", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_intentCheckCompleted_0_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onIntentCheckCompleted()); })("uploadStateChanged", function ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template_mj_message_input_uploadStateChanged_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onUploadStateChanged($event)); });
149
186
  i0.ɵɵelementEnd();
150
187
  } if (rf & 2) {
151
- const inputRef_r10 = ctx.$implicit;
188
+ const inputRef_r12 = ctx.$implicit;
152
189
  const ctx_r2 = i0.ɵɵnextContext(3);
153
- i0.ɵɵproperty("hidden", inputRef_r10.conversationId !== ctx_r2.conversationId)("conversationId", inputRef_r10.conversationId)("conversationName", inputRef_r10.conversationName)("currentUser", ctx_r2.currentUser)("conversationHistory", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.messages : i0.ɵɵpureFunction0(11, _c2))("artifactsByDetailId", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.artifactsByDetailId : ctx_r2.emptyArtifactsMap)("systemArtifactsByDetailId", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.systemArtifactsByDetailId : ctx_r2.emptyArtifactsMap)("agentRunsByDetailId", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.agentRunsByDetailId : ctx_r2.emptyAgentRunsMap)("inProgressMessageIds", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.inProgressMessageIds : ctx_r2.emptyInProgressIds)("disabled", ctx_r2.isProcessing)("initialMessage", inputRef_r10.conversationId === ctx_r2.conversationId ? ctx_r2.pendingMessage : null);
190
+ i0.ɵɵproperty("hidden", inputRef_r12.conversationId !== ctx_r2.conversationId)("conversationId", inputRef_r12.conversationId)("conversationName", inputRef_r12.conversationName)("currentUser", ctx_r2.currentUser)("conversationHistory", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.messages : i0.ɵɵpureFunction0(16, _c2))("artifactsByDetailId", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.artifactsByDetailId : ctx_r2.emptyArtifactsMap)("systemArtifactsByDetailId", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.systemArtifactsByDetailId : ctx_r2.emptyArtifactsMap)("agentRunsByDetailId", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.agentRunsByDetailId : ctx_r2.emptyAgentRunsMap)("inProgressMessageIds", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.inProgressMessageIds : ctx_r2.emptyInProgressIds)("disabled", ctx_r2.isProcessing)("enableAttachments", ctx_r2.enableAttachments)("maxAttachments", ctx_r2.maxAttachments)("maxAttachmentSizeBytes", ctx_r2.maxAttachmentSizeBytes)("acceptedFileTypes", ctx_r2.acceptedFileTypes)("initialMessage", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.pendingMessage : null)("initialAttachments", inputRef_r12.conversationId === ctx_r2.conversationId ? ctx_r2.pendingAttachments : null);
154
191
  } }
155
- function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf, ctx) { if (rf & 1) {
156
- i0.ɵɵelementStart(0, "div", 43);
157
- i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_6_Conditional_7_For_2_Template, 2, 12, "mj-message-input", 47, _forTrack0);
192
+ function ConversationChatAreaComponent_Conditional_6_Conditional_8_Template(rf, ctx) { if (rf & 1) {
193
+ i0.ɵɵelementStart(0, "div", 52);
194
+ i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_6_Conditional_8_For_2_Template, 2, 17, "mj-message-input", 57, _forTrack0);
158
195
  i0.ɵɵelementEnd();
159
196
  } if (rf & 2) {
160
197
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -162,37 +199,41 @@ function ConversationChatAreaComponent_Conditional_6_Conditional_7_Template(rf,
162
199
  i0.ɵɵrepeater(ctx_r2.getCachedInputs());
163
200
  } }
164
201
  function ConversationChatAreaComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
165
- const _r7 = i0.ɵɵgetCurrentView();
166
- i0.ɵɵelementStart(0, "div", 8)(1, "div", 38, 0);
167
- i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_6_Template_div_scroll_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.checkScroll()); });
168
- i0.ɵɵelementStart(3, "mj-conversation-message-list", 39);
169
- i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_replyInThread_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_viewThread_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_retryMessage_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRetryMessage($event)); })("testFeedbackMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_testFeedbackMessage_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTestFeedbackMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_artifactClicked_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_messageEdited_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_openEntityRecord_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_suggestedResponseSelected_3_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSuggestedResponseSelected($event)); });
202
+ const _r9 = i0.ɵɵgetCurrentView();
203
+ i0.ɵɵelementStart(0, "div", 8);
204
+ i0.ɵɵtemplate(1, ConversationChatAreaComponent_Conditional_6_Conditional_1_Template, 2, 1, "div", 46);
205
+ i0.ɵɵelementStart(2, "div", 47, 0);
206
+ i0.ɵɵlistener("scroll", function ConversationChatAreaComponent_Conditional_6_Template_div_scroll_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.checkScroll()); });
207
+ i0.ɵɵelementStart(4, "mj-conversation-message-list", 48);
208
+ i0.ɵɵlistener("replyInThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_replyInThread_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onReplyInThread($event)); })("viewThread", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_viewThread_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onViewThread($event)); })("retryMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_retryMessage_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onRetryMessage($event)); })("testFeedbackMessage", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_testFeedbackMessage_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onTestFeedbackMessage($event)); })("artifactClicked", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_artifactClicked_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactClicked($event)); })("messageEdited", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_messageEdited_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onMessageEdited($event)); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_openEntityRecord_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); })("suggestedResponseSelected", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_suggestedResponseSelected_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSuggestedResponseSelected($event)); })("attachmentClicked", function ConversationChatAreaComponent_Conditional_6_Template_mj_conversation_message_list_attachmentClicked_4_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onAttachmentClicked($event)); });
170
209
  i0.ɵɵelementEnd();
171
- i0.ɵɵtemplate(4, ConversationChatAreaComponent_Conditional_6_span_4_Template, 2, 0, "span", 40);
210
+ i0.ɵɵtemplate(5, ConversationChatAreaComponent_Conditional_6_span_5_Template, 2, 0, "span", 49);
172
211
  i0.ɵɵelementEnd();
173
- i0.ɵɵelementStart(5, "div", 41);
174
- i0.ɵɵtemplate(6, ConversationChatAreaComponent_Conditional_6_Conditional_6_Template, 2, 0, "div", 42)(7, ConversationChatAreaComponent_Conditional_6_Conditional_7_Template, 3, 0, "div", 43);
212
+ i0.ɵɵelementStart(6, "div", 50);
213
+ i0.ɵɵtemplate(7, ConversationChatAreaComponent_Conditional_6_Conditional_7_Template, 2, 0, "div", 51)(8, ConversationChatAreaComponent_Conditional_6_Conditional_8_Template, 3, 0, "div", 52);
175
214
  i0.ɵɵelementEnd()();
176
215
  } if (rf & 2) {
177
216
  const ctx_r2 = i0.ɵɵnextContext();
217
+ i0.ɵɵadvance();
218
+ i0.ɵɵconditional(ctx_r2.isUploadingAttachments ? 1 : -1);
178
219
  i0.ɵɵadvance(3);
179
- i0.ɵɵproperty("messages", ctx_r2.messages)("conversation", ctx_r2.conversation)("currentUser", ctx_r2.currentUser)("isProcessing", ctx_r2.isProcessing)("artifactMap", ctx_r2.effectiveArtifactsMap)("agentRunMap", ctx_r2.agentRunsByDetailId)("ratingsMap", ctx_r2.ratingsByDetailId)("userAvatarMap", ctx_r2.userAvatarMap);
220
+ i0.ɵɵproperty("messages", ctx_r2.messages)("conversation", ctx_r2.conversation)("currentUser", ctx_r2.currentUser)("isProcessing", ctx_r2.isProcessing)("artifactMap", ctx_r2.effectiveArtifactsMap)("agentRunMap", ctx_r2.agentRunsByDetailId)("ratingsMap", ctx_r2.ratingsByDetailId)("userAvatarMap", ctx_r2.userAvatarMap)("attachmentsMap", ctx_r2.attachmentsByDetailId);
180
221
  i0.ɵɵadvance();
181
222
  i0.ɵɵproperty("ngIf", ctx_r2.showScrollToBottomIcon && ctx_r2.messages && ctx_r2.messages.length > 0);
182
223
  i0.ɵɵadvance(2);
183
- i0.ɵɵconditional(ctx_r2.isLoadingPeripheralData ? 6 : 7);
224
+ i0.ɵɵconditional(ctx_r2.isLoadingPeripheralData ? 7 : 8);
184
225
  } }
185
226
  function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template(rf, ctx) { if (rf & 1) {
186
- const _r12 = i0.ɵɵgetCurrentView();
187
- i0.ɵɵelementStart(0, "div", 52);
188
- i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeTouchStart($event)); });
227
+ const _r14 = i0.ɵɵgetCurrentView();
228
+ i0.ɵɵelementStart(0, "div", 62);
229
+ i0.ɵɵlistener("mousedown", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeStart($event)); })("touchstart", function ConversationChatAreaComponent_Conditional_7_Conditional_0_Template_div_touchstart_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onResizeTouchStart($event)); });
189
230
  i0.ɵɵelementEnd();
190
231
  } }
191
232
  function ConversationChatAreaComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
192
- const _r11 = i0.ɵɵgetCurrentView();
193
- i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_7_Conditional_0_Template, 1, 0, "div", 49);
194
- i0.ɵɵelementStart(1, "div", 50)(2, "mj-artifact-viewer-panel", 51);
195
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSaveToCollectionRequested($event)); })("navigateToLink", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_navigateToLink_2_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactLinkNavigation($event)); })("shareRequested", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_shareRequested_2_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactShareRequested($event)); })("maximizeToggled", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_maximizeToggled_2_listener() { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleMaximizeArtifactPane()); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_openEntityRecord_2_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
233
+ const _r13 = i0.ɵɵgetCurrentView();
234
+ i0.ɵɵtemplate(0, ConversationChatAreaComponent_Conditional_7_Conditional_0_Template, 1, 0, "div", 59);
235
+ i0.ɵɵelementStart(1, "div", 60)(2, "mj-artifact-viewer-panel", 61);
236
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_closed_2_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCloseArtifactPanel()); })("saveToCollectionRequested", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_saveToCollectionRequested_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onSaveToCollectionRequested($event)); })("navigateToLink", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_navigateToLink_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactLinkNavigation($event)); })("shareRequested", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_shareRequested_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onArtifactShareRequested($event)); })("maximizeToggled", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_maximizeToggled_2_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleMaximizeArtifactPane()); })("openEntityRecord", function ConversationChatAreaComponent_Conditional_7_Template_mj_artifact_viewer_panel_openEntityRecord_2_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onOpenEntityRecord($event)); });
196
237
  i0.ɵɵelementEnd()();
197
238
  } if (rf & 2) {
198
239
  const ctx_r2 = i0.ɵɵnextContext();
@@ -204,29 +245,29 @@ function ConversationChatAreaComponent_Conditional_7_Template(rf, ctx) { if (rf
204
245
  i0.ɵɵproperty("artifactId", ctx_r2.selectedArtifactId)("currentUser", ctx_r2.currentUser)("environmentId", ctx_r2.environmentId)("versionNumber", ctx_r2.selectedVersionNumber)("viewContext", "conversation")("canShare", ctx_r2.canShareSelectedArtifact)("canEdit", ctx_r2.canEditSelectedArtifact)("isMaximized", ctx_r2.isArtifactPaneMaximized)("refreshTrigger", ctx_r2.artifactViewerRefresh$);
205
246
  } }
206
247
  function ConversationChatAreaComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
207
- const _r13 = i0.ɵɵgetCurrentView();
208
- i0.ɵɵelementStart(0, "mj-thread-panel", 53);
209
- i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLocalThreadClosed()); })("replyAdded", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_replyAdded_0_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onThreadReplyAdded($event)); });
248
+ const _r15 = i0.ɵɵgetCurrentView();
249
+ i0.ɵɵelementStart(0, "mj-thread-panel", 63);
250
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_closed_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onLocalThreadClosed()); })("replyAdded", function ConversationChatAreaComponent_Conditional_9_Template_mj_thread_panel_replyAdded_0_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onThreadReplyAdded($event)); });
210
251
  i0.ɵɵelementEnd();
211
252
  } if (rf & 2) {
212
253
  const ctx_r2 = i0.ɵɵnextContext();
213
254
  i0.ɵɵproperty("parentMessageId", ctx_r2.threadId)("conversationId", ctx_r2.conversationId || "")("currentUser", ctx_r2.currentUser);
214
255
  } }
215
256
  function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
216
- const _r14 = i0.ɵɵgetCurrentView();
217
- i0.ɵɵelementStart(0, "div", 54);
218
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
219
- i0.ɵɵelementStart(1, "div", 55);
220
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
221
- i0.ɵɵelementStart(2, "div", 56)(3, "h3");
257
+ const _r16 = i0.ɵɵgetCurrentView();
258
+ i0.ɵɵelementStart(0, "div", 64);
259
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
260
+ i0.ɵɵelementStart(1, "div", 65);
261
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r16); return i0.ɵɵresetView($event.stopPropagation()); });
262
+ i0.ɵɵelementStart(2, "div", 66)(3, "h3");
222
263
  i0.ɵɵtext(4, "Assign Project");
223
264
  i0.ɵɵelementEnd();
224
- i0.ɵɵelementStart(5, "button", 57);
225
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
226
- i0.ɵɵelement(6, "i", 58);
265
+ i0.ɵɵelementStart(5, "button", 67);
266
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_12_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showProjectSelector = false); });
267
+ i0.ɵɵelement(6, "i", 68);
227
268
  i0.ɵɵelementEnd()();
228
- i0.ɵɵelementStart(7, "div", 59)(8, "mj-project-selector", 60);
229
- i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_12_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onProjectSelected($event)); });
269
+ i0.ɵɵelementStart(7, "div", 69)(8, "mj-project-selector", 70);
270
+ i0.ɵɵlistener("projectSelected", function ConversationChatAreaComponent_Conditional_12_Template_mj_project_selector_projectSelected_8_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onProjectSelected($event)); });
230
271
  i0.ɵɵelementEnd()()()();
231
272
  } if (rf & 2) {
232
273
  const ctx_r2 = i0.ɵɵnextContext();
@@ -234,10 +275,10 @@ function ConversationChatAreaComponent_Conditional_12_Template(rf, ctx) { if (rf
234
275
  i0.ɵɵproperty("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("selectedProjectId", ctx_r2.conversation.ProjectID);
235
276
  } }
236
277
  function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template(rf, ctx) { if (rf & 1) {
237
- const _r16 = i0.ɵɵgetCurrentView();
238
- i0.ɵɵelementStart(0, "button", 67);
239
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleSystemArtifacts()); });
240
- i0.ɵɵelement(1, "i", 68);
278
+ const _r18 = i0.ɵɵgetCurrentView();
279
+ i0.ɵɵelementStart(0, "button", 77);
280
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleSystemArtifacts()); });
281
+ i0.ɵɵelement(1, "i", 78);
241
282
  i0.ɵɵelementStart(2, "span");
242
283
  i0.ɵɵtext(3);
243
284
  i0.ɵɵelementEnd()();
@@ -248,109 +289,109 @@ function ConversationChatAreaComponent_Conditional_13_Conditional_6_Template(rf,
248
289
  i0.ɵɵtextInterpolate1("", ctx_r2.showSystemArtifacts ? "Hide" : "Show", " System");
249
290
  } }
250
291
  function ConversationChatAreaComponent_Conditional_13_Conditional_10_Template(rf, ctx) { if (rf & 1) {
251
- i0.ɵɵelementStart(0, "div", 65);
252
- i0.ɵɵelement(1, "i", 69);
253
- i0.ɵɵelementStart(2, "p", 70);
292
+ i0.ɵɵelementStart(0, "div", 75);
293
+ i0.ɵɵelement(1, "i", 79);
294
+ i0.ɵɵelementStart(2, "p", 80);
254
295
  i0.ɵɵtext(3, "No artifacts in this conversation yet");
255
296
  i0.ɵɵelementEnd()();
256
297
  } }
257
298
  function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
258
299
  i0.ɵɵtext(0);
259
300
  } if (rf & 2) {
260
- const artifact_r18 = i0.ɵɵnextContext().$implicit;
261
- i0.ɵɵtextInterpolate1(" ", artifact_r18.versionCount, " versions ");
301
+ const artifact_r20 = i0.ɵɵnextContext().$implicit;
302
+ i0.ɵɵtextInterpolate1(" ", artifact_r20.versionCount, " versions ");
262
303
  } }
263
304
  function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_9_Template(rf, ctx) { if (rf & 1) {
264
305
  i0.ɵɵtext(0, " 1 version ");
265
306
  } }
266
307
  function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
267
- const _r19 = i0.ɵɵgetCurrentView();
268
- i0.ɵɵelementStart(0, "button", 82);
269
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r19); const artifact_r18 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleArtifactExpansion(artifact_r18.artifactId, $event)); });
270
- i0.ɵɵelement(1, "i", 83);
308
+ const _r21 = i0.ɵɵgetCurrentView();
309
+ i0.ɵɵelementStart(0, "button", 92);
310
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r21); const artifact_r20 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleArtifactExpansion(artifact_r20.artifactId, $event)); });
311
+ i0.ɵɵelement(1, "i", 93);
271
312
  i0.ɵɵelementEnd();
272
313
  } if (rf & 2) {
273
- const artifact_r18 = i0.ɵɵnextContext().$implicit;
314
+ const artifact_r20 = i0.ɵɵnextContext().$implicit;
274
315
  const ctx_r2 = i0.ɵɵnextContext(2);
275
316
  i0.ɵɵadvance();
276
- i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedArtifactId !== artifact_r18.artifactId)("fa-chevron-up", ctx_r2.expandedArtifactId === artifact_r18.artifactId);
317
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r2.expandedArtifactId !== artifact_r20.artifactId)("fa-chevron-up", ctx_r2.expandedArtifactId === artifact_r20.artifactId);
277
318
  } }
278
319
  function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
279
- const _r20 = i0.ɵɵgetCurrentView();
280
- i0.ɵɵelementStart(0, "div", 85);
281
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r21 = i0.ɵɵrestoreView(_r20).$implicit; const artifact_r18 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openArtifactFromModal(artifact_r18.artifactId, version_r21.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
282
- i0.ɵɵelementStart(1, "span", 86);
320
+ const _r22 = i0.ɵɵgetCurrentView();
321
+ i0.ɵɵelementStart(0, "div", 95);
322
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template_div_click_0_listener($event) { const version_r23 = i0.ɵɵrestoreView(_r22).$implicit; const artifact_r20 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.openArtifactFromModal(artifact_r20.artifactId, version_r23.versionNumber); return i0.ɵɵresetView($event.stopPropagation()); });
323
+ i0.ɵɵelementStart(1, "span", 96);
283
324
  i0.ɵɵtext(2);
284
325
  i0.ɵɵelementEnd();
285
- i0.ɵɵelementStart(3, "span", 87);
326
+ i0.ɵɵelementStart(3, "span", 97);
286
327
  i0.ɵɵtext(4, "Open this version");
287
328
  i0.ɵɵelementEnd();
288
- i0.ɵɵelement(5, "i", 88);
329
+ i0.ɵɵelement(5, "i", 98);
289
330
  i0.ɵɵelementEnd();
290
331
  } if (rf & 2) {
291
- const version_r21 = ctx.$implicit;
332
+ const version_r23 = ctx.$implicit;
292
333
  i0.ɵɵadvance(2);
293
- i0.ɵɵtextInterpolate1("v", version_r21.versionNumber, "");
334
+ i0.ɵɵtextInterpolate1("v", version_r23.versionNumber, "");
294
335
  } }
295
336
  function ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template(rf, ctx) { if (rf & 1) {
296
- i0.ɵɵelementStart(0, "div", 81);
297
- i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template, 6, 1, "div", 84, _forTrack2);
337
+ i0.ɵɵelementStart(0, "div", 91);
338
+ i0.ɵɵrepeaterCreate(1, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_For_2_Template, 6, 1, "div", 94, _forTrack2);
298
339
  i0.ɵɵelementEnd();
299
340
  } if (rf & 2) {
300
- const artifact_r18 = i0.ɵɵnextContext().$implicit;
341
+ const artifact_r20 = i0.ɵɵnextContext().$implicit;
301
342
  i0.ɵɵadvance();
302
- i0.ɵɵrepeater(artifact_r18.versions);
343
+ i0.ɵɵrepeater(artifact_r20.versions);
303
344
  } }
304
345
  function ConversationChatAreaComponent_Conditional_13_For_12_Template(rf, ctx) { if (rf & 1) {
305
- const _r17 = i0.ɵɵgetCurrentView();
306
- i0.ɵɵelementStart(0, "div", 71)(1, "div", 72);
307
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Template_div_click_1_listener() { const artifact_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openArtifactFromModal(artifact_r18.artifactId)); });
308
- i0.ɵɵelementStart(2, "div", 73);
309
- i0.ɵɵelement(3, "i", 74);
346
+ const _r19 = i0.ɵɵgetCurrentView();
347
+ i0.ɵɵelementStart(0, "div", 81)(1, "div", 82);
348
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_For_12_Template_div_click_1_listener() { const artifact_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.openArtifactFromModal(artifact_r20.artifactId)); });
349
+ i0.ɵɵelementStart(2, "div", 83);
350
+ i0.ɵɵelement(3, "i", 84);
310
351
  i0.ɵɵelementEnd();
311
- i0.ɵɵelementStart(4, "div", 75)(5, "div", 76);
352
+ i0.ɵɵelementStart(4, "div", 85)(5, "div", 86);
312
353
  i0.ɵɵtext(6);
313
354
  i0.ɵɵelementEnd();
314
- i0.ɵɵelementStart(7, "div", 77);
355
+ i0.ɵɵelementStart(7, "div", 87);
315
356
  i0.ɵɵtemplate(8, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_8_Template, 1, 1)(9, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_9_Template, 1, 0);
316
357
  i0.ɵɵelementEnd()();
317
- i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template, 2, 4, "button", 78);
318
- i0.ɵɵelementStart(11, "div", 79);
319
- i0.ɵɵelement(12, "i", 80);
358
+ i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_10_Template, 2, 4, "button", 88);
359
+ i0.ɵɵelementStart(11, "div", 89);
360
+ i0.ɵɵelement(12, "i", 90);
320
361
  i0.ɵɵelementEnd()();
321
- i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template, 3, 0, "div", 81);
362
+ i0.ɵɵtemplate(13, ConversationChatAreaComponent_Conditional_13_For_12_Conditional_13_Template, 3, 0, "div", 91);
322
363
  i0.ɵɵelementEnd();
323
364
  } if (rf & 2) {
324
- const artifact_r18 = ctx.$implicit;
365
+ const artifact_r20 = ctx.$implicit;
325
366
  const ctx_r2 = i0.ɵɵnextContext(2);
326
- i0.ɵɵclassProp("expanded", ctx_r2.expandedArtifactId === artifact_r18.artifactId)("system-artifact", artifact_r18.visibility === "System Only");
367
+ i0.ɵɵclassProp("expanded", ctx_r2.expandedArtifactId === artifact_r20.artifactId)("system-artifact", artifact_r20.visibility === "System Only");
327
368
  i0.ɵɵadvance(6);
328
- i0.ɵɵtextInterpolate(artifact_r18.name);
369
+ i0.ɵɵtextInterpolate(artifact_r20.name);
329
370
  i0.ɵɵadvance(2);
330
- i0.ɵɵconditional(artifact_r18.versionCount > 1 ? 8 : 9);
371
+ i0.ɵɵconditional(artifact_r20.versionCount > 1 ? 8 : 9);
331
372
  i0.ɵɵadvance(2);
332
- i0.ɵɵconditional(artifact_r18.versionCount > 1 ? 10 : -1);
373
+ i0.ɵɵconditional(artifact_r20.versionCount > 1 ? 10 : -1);
333
374
  i0.ɵɵadvance(3);
334
- i0.ɵɵconditional(ctx_r2.expandedArtifactId === artifact_r18.artifactId && artifact_r18.versionCount > 1 ? 13 : -1);
375
+ i0.ɵɵconditional(ctx_r2.expandedArtifactId === artifact_r20.artifactId && artifact_r20.versionCount > 1 ? 13 : -1);
335
376
  } }
336
377
  function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
337
- const _r15 = i0.ɵɵgetCurrentView();
338
- i0.ɵɵelementStart(0, "div", 54);
339
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
340
- i0.ɵɵelementStart(1, "div", 61);
341
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r15); return i0.ɵɵresetView($event.stopPropagation()); });
342
- i0.ɵɵelementStart(2, "div", 56)(3, "h3");
378
+ const _r17 = i0.ɵɵgetCurrentView();
379
+ i0.ɵɵelementStart(0, "div", 64);
380
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
381
+ i0.ɵɵelementStart(1, "div", 71);
382
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r17); return i0.ɵɵresetView($event.stopPropagation()); });
383
+ i0.ɵɵelementStart(2, "div", 66)(3, "h3");
343
384
  i0.ɵɵtext(4, "Conversation Artifacts");
344
385
  i0.ɵɵelementEnd();
345
- i0.ɵɵelementStart(5, "div", 62);
346
- i0.ɵɵtemplate(6, ConversationChatAreaComponent_Conditional_13_Conditional_6_Template, 4, 3, "button", 63);
347
- i0.ɵɵelementStart(7, "button", 57);
348
- i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
349
- i0.ɵɵelement(8, "i", 58);
386
+ i0.ɵɵelementStart(5, "div", 72);
387
+ i0.ɵɵtemplate(6, ConversationChatAreaComponent_Conditional_13_Conditional_6_Template, 4, 3, "button", 73);
388
+ i0.ɵɵelementStart(7, "button", 67);
389
+ i0.ɵɵlistener("click", function ConversationChatAreaComponent_Conditional_13_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r17); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showArtifactsModal = false); });
390
+ i0.ɵɵelement(8, "i", 68);
350
391
  i0.ɵɵelementEnd()()();
351
- i0.ɵɵelementStart(9, "div", 64);
352
- i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_Conditional_10_Template, 4, 0, "div", 65);
353
- i0.ɵɵrepeaterCreate(11, ConversationChatAreaComponent_Conditional_13_For_12_Template, 14, 8, "div", 66, _forTrack1);
392
+ i0.ɵɵelementStart(9, "div", 74);
393
+ i0.ɵɵtemplate(10, ConversationChatAreaComponent_Conditional_13_Conditional_10_Template, 4, 0, "div", 75);
394
+ i0.ɵɵrepeaterCreate(11, ConversationChatAreaComponent_Conditional_13_For_12_Template, 14, 8, "div", 76, _forTrack1);
354
395
  i0.ɵɵelementEnd()()();
355
396
  } if (rf & 2) {
356
397
  const ctx_r2 = i0.ɵɵnextContext();
@@ -362,14 +403,23 @@ function ConversationChatAreaComponent_Conditional_13_Template(rf, ctx) { if (rf
362
403
  i0.ɵɵrepeater(ctx_r2.getArtifactsArray());
363
404
  } }
364
405
  function ConversationChatAreaComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
365
- const _r22 = i0.ɵɵgetCurrentView();
366
- i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 89);
367
- i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerSaved($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerCancelled()); });
406
+ const _r24 = i0.ɵɵgetCurrentView();
407
+ i0.ɵɵelementStart(0, "mj-artifact-collection-picker-modal", 99);
408
+ i0.ɵɵlistener("saved", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_saved_0_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerSaved($event)); })("cancelled", function ConversationChatAreaComponent_Conditional_14_Template_mj_artifact_collection_picker_modal_cancelled_0_listener() { i0.ɵɵrestoreView(_r24); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onCollectionPickerCancelled()); });
368
409
  i0.ɵɵelementEnd();
369
410
  } if (rf & 2) {
370
411
  const ctx_r2 = i0.ɵɵnextContext();
371
412
  i0.ɵɵproperty("isOpen", ctx_r2.showCollectionPicker)("environmentId", ctx_r2.environmentId)("currentUser", ctx_r2.currentUser)("excludeCollectionIds", ctx_r2.collectionPickerExcludedIds);
372
413
  } }
414
+ function ConversationChatAreaComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
415
+ const _r25 = i0.ɵɵgetCurrentView();
416
+ i0.ɵɵelementStart(0, "mj-image-viewer", 100);
417
+ i0.ɵɵlistener("closed", function ConversationChatAreaComponent_Conditional_15_Template_mj_image_viewer_closed_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onImageViewerClosed()); });
418
+ i0.ɵɵelementEnd();
419
+ } if (rf & 2) {
420
+ const ctx_r2 = i0.ɵɵnextContext();
421
+ i0.ɵɵproperty("imageUrl", ctx_r2.selectedImageUrl)("alt", ctx_r2.selectedImageAlt)("fileName", ctx_r2.selectedImageFileName)("visible", ctx_r2.showImageViewer);
422
+ } }
373
423
  export class ConversationChatAreaComponent {
374
424
  conversationData;
375
425
  agentStateService;
@@ -379,6 +429,8 @@ export class ConversationChatAreaComponent {
379
429
  mentionAutocompleteService;
380
430
  artifactPermissionService;
381
431
  dialogService;
432
+ attachmentService;
433
+ streamingService;
382
434
  environmentId;
383
435
  currentUser;
384
436
  // LOCAL STATE INPUTS - passed from parent workspace
@@ -399,19 +451,45 @@ export class ConversationChatAreaComponent {
399
451
  conversation = null;
400
452
  threadId = null;
401
453
  isNewConversation = false;
402
- pendingMessage = null;
454
+ // Using getter/setter to ensure correct type handling
455
+ _pendingMessage = null;
456
+ set pendingMessage(value) {
457
+ // Handle case where an object is incorrectly passed
458
+ if (value && typeof value === 'object' && 'text' in value) {
459
+ this._pendingMessage = value.text;
460
+ }
461
+ else {
462
+ this._pendingMessage = value;
463
+ }
464
+ }
465
+ get pendingMessage() {
466
+ return this._pendingMessage;
467
+ }
468
+ // Using getter/setter to ensure reactivity
469
+ _pendingAttachments = null;
470
+ set pendingAttachments(value) {
471
+ this._pendingAttachments = value;
472
+ }
473
+ get pendingAttachments() {
474
+ return this._pendingAttachments;
475
+ }
403
476
  pendingArtifactId = null;
404
477
  pendingArtifactVersionNumber = null;
478
+ // Sidebar toggle - when true, shows toggle button in header to expand sidebar
479
+ showSidebarToggle = false;
405
480
  conversationRenamed = new EventEmitter();
406
481
  openEntityRecord = new EventEmitter();
407
482
  taskClicked = new EventEmitter();
408
483
  artifactLinkClicked = new EventEmitter();
484
+ sidebarToggleClicked = new EventEmitter();
409
485
  // STATE CHANGE OUTPUTS - notify parent of state changes
486
+ // conversationCreated now includes pendingMessage and pendingAttachments to ensure atomic state update
410
487
  conversationCreated = new EventEmitter();
411
488
  threadOpened = new EventEmitter();
412
489
  threadClosed = new EventEmitter();
413
490
  pendingArtifactConsumed = new EventEmitter();
414
491
  pendingMessageConsumed = new EventEmitter();
492
+ // pendingMessageRequested is deprecated - use conversationCreated with pendingMessage instead
415
493
  pendingMessageRequested = new EventEmitter();
416
494
  scrollContainer;
417
495
  messageInputComponents;
@@ -419,7 +497,7 @@ export class ConversationChatAreaComponent {
419
497
  messages = [];
420
498
  showScrollToBottomIcon = false;
421
499
  scrollToBottom = false;
422
- lastLoadedConversationId = null; // Track which conversation's peripheral data was loaded
500
+ loadedPeripheralConversationIds = new Set(); // Track ALL conversations whose peripheral data was loaded
423
501
  currentlyLoadingConversationId = null; // Track which conversation is currently being loaded
424
502
  isProcessing = false;
425
503
  intentCheckMessage = null; // Temporary message shown during intent checking
@@ -472,15 +550,15 @@ export class ConversationChatAreaComponent {
472
550
  * Ratings by conversation detail ID (parsed from RatingsJSON)
473
551
  */
474
552
  ratingsByDetailId = new Map();
553
+ /**
554
+ * Attachments by conversation detail ID (loaded from ConversationDetailAttachments)
555
+ */
556
+ attachmentsByDetailId = new Map();
475
557
  /**
476
558
  * In-progress message IDs for streaming reconnection
477
559
  * Passed to message-input component to reconnect PubSub updates
478
560
  */
479
561
  inProgressMessageIds = [];
480
- // Timer for smooth agent run UI updates (updates every second while agent runs)
481
- agentRunUpdateTimer = null;
482
- // Track previous message statuses to detect completions after navigation
483
- previousMessageStatuses = new Map();
484
562
  // Cache of message-input metadata for rendering multiple instances
485
563
  // Prevents destruction/recreation when switching conversations for performance
486
564
  messageInputMetadataCache = new Map();
@@ -492,6 +570,8 @@ export class ConversationChatAreaComponent {
492
570
  isLoadingPeripheralData = false;
493
571
  // Subject to trigger artifact viewer refresh when new version is created
494
572
  artifactViewerRefresh$ = new Subject();
573
+ // Subject for component destruction cleanup
574
+ destroy$ = new Subject();
495
575
  // Track initialization state to prevent loading messages before agents are ready
496
576
  isInitialized = false;
497
577
  // Resize state
@@ -500,7 +580,22 @@ export class ConversationChatAreaComponent {
500
580
  startWidth = 0;
501
581
  // LocalStorage key
502
582
  ARTIFACT_PANE_WIDTH_KEY = 'mj-conversations-artifact-pane-width';
503
- constructor(conversationData, agentStateService, conversationAgentService, activeTasks, cdr, mentionAutocompleteService, artifactPermissionService, dialogService) {
583
+ // Image viewer state
584
+ showImageViewer = false;
585
+ selectedImageUrl = '';
586
+ selectedImageAlt = '';
587
+ selectedImageFileName = '';
588
+ // Upload indicator state (shown centered in conversation area)
589
+ isUploadingAttachments = false;
590
+ uploadingMessage = '';
591
+ // Attachment support based on agent modalities
592
+ // Computed from conversation manager (Sage) and any previous agent in conversation
593
+ enableAttachments = false;
594
+ maxAttachments = 10;
595
+ maxAttachmentSizeBytes = 20 * 1024 * 1024; // 20MB default
596
+ acceptedFileTypes = 'image/*';
597
+ conversationManagerAgent = null;
598
+ constructor(conversationData, agentStateService, conversationAgentService, activeTasks, cdr, mentionAutocompleteService, artifactPermissionService, dialogService, attachmentService, streamingService) {
504
599
  this.conversationData = conversationData;
505
600
  this.agentStateService = agentStateService;
506
601
  this.conversationAgentService = conversationAgentService;
@@ -509,6 +604,8 @@ export class ConversationChatAreaComponent {
509
604
  this.mentionAutocompleteService = mentionAutocompleteService;
510
605
  this.artifactPermissionService = artifactPermissionService;
511
606
  this.dialogService = dialogService;
607
+ this.attachmentService = attachmentService;
608
+ this.streamingService = streamingService;
512
609
  }
513
610
  async ngOnInit() {
514
611
  // The workspace component initializes AI Engine and mention service before
@@ -519,8 +616,22 @@ export class ConversationChatAreaComponent {
519
616
  console.warn('⚠️ Mention autocomplete not initialized by workspace, initializing now...');
520
617
  await this.mentionAutocompleteService.initialize(this.currentUser);
521
618
  }
619
+ // Initialize attachment support based on agent modalities
620
+ await this.initializeAttachmentSupport();
522
621
  // Load saved artifact pane width
523
622
  this.loadArtifactPaneWidth();
623
+ // Subscribe to completion events from streaming service (PubSub-based, replaces polling)
624
+ // This handles real-time completion notifications without timer-based polling
625
+ this.streamingService.completionEvents$
626
+ .pipe(takeUntil(this.destroy$))
627
+ .subscribe(async (event) => {
628
+ // Only handle if it's for a message in our current conversation
629
+ const message = this.messages.find(m => m.ID === event.conversationDetailId);
630
+ if (message) {
631
+ LogStatusEx({ message: `🎉 Received completion event for message ${event.conversationDetailId}`, verboseOnly: true });
632
+ await this.handleMessageCompletion(message, event.agentRunId);
633
+ }
634
+ });
524
635
  // Mark as initialized so setter can trigger conversation changes
525
636
  this.isInitialized = true;
526
637
  // Initial load if there's already an active conversation
@@ -533,6 +644,70 @@ export class ConversationChatAreaComponent {
533
644
  window.addEventListener('touchmove', this.onResizeTouchMove.bind(this));
534
645
  window.addEventListener('touchend', this.onResizeTouchEnd.bind(this));
535
646
  }
647
+ /**
648
+ * Initializes attachment support by checking if the conversation manager agent (Sage)
649
+ * or any recent agent in the conversation supports non-text input modalities.
650
+ */
651
+ async initializeAttachmentSupport() {
652
+ try {
653
+ // Ensure AIEngineBase is configured with modality data
654
+ await AIEngineBase.Instance.Config(false);
655
+ // Get the conversation manager agent (Sage)
656
+ this.conversationManagerAgent = await this.conversationAgentService.getConversationManagerAgent();
657
+ if (this.conversationManagerAgent?.ID) {
658
+ // Get attachment limits from agent metadata (uses Agent → Model → System → Default cascade)
659
+ const limits = AIEngineBase.Instance.GetAgentAttachmentLimits(this.conversationManagerAgent.ID);
660
+ this.enableAttachments = limits.enabled;
661
+ this.maxAttachments = limits.maxAttachments;
662
+ this.maxAttachmentSizeBytes = limits.maxAttachmentSizeBytes;
663
+ this.acceptedFileTypes = limits.acceptedFileTypes;
664
+ LogStatusEx({ message: `Attachment support initialized: ${this.enableAttachments} (max ${this.maxAttachments}, ${(this.maxAttachmentSizeBytes / 1024 / 1024).toFixed(0)}MB)`, verboseOnly: true });
665
+ }
666
+ else {
667
+ // Default to false if we can't determine
668
+ this.enableAttachments = false;
669
+ LogStatusEx({ message: 'Attachment support disabled: conversation manager agent not available', verboseOnly: true });
670
+ }
671
+ }
672
+ catch (error) {
673
+ console.warn('Failed to initialize attachment support:', error);
674
+ this.enableAttachments = false;
675
+ }
676
+ }
677
+ /**
678
+ * Updates attachment support based on the current conversation context.
679
+ * Called when conversation changes to check if any agent in the conversation supports attachments.
680
+ */
681
+ updateAttachmentSupport() {
682
+ // Determine which agent to use for limits - prefer last non-Sage agent, fall back to Sage
683
+ let agentIdForLimits = this.conversationManagerAgent?.ID || null;
684
+ // Check if any previous non-Sage agent in the conversation supports attachments
685
+ if (this.messages.length > 0) {
686
+ const lastNonSageAgent = this.messages
687
+ .slice()
688
+ .reverse()
689
+ .find(msg => msg.Role === 'AI' &&
690
+ msg.AgentID &&
691
+ msg.AgentID !== this.conversationManagerAgent?.ID);
692
+ if (lastNonSageAgent?.AgentID) {
693
+ // Check if this agent supports attachments
694
+ if (AIEngineBase.Instance.AgentSupportsAttachments(lastNonSageAgent.AgentID)) {
695
+ agentIdForLimits = lastNonSageAgent.AgentID;
696
+ }
697
+ }
698
+ }
699
+ // Get limits from the determined agent
700
+ if (agentIdForLimits) {
701
+ const limits = AIEngineBase.Instance.GetAgentAttachmentLimits(agentIdForLimits);
702
+ this.enableAttachments = limits.enabled;
703
+ this.maxAttachments = limits.maxAttachments;
704
+ this.maxAttachmentSizeBytes = limits.maxAttachmentSizeBytes;
705
+ this.acceptedFileTypes = limits.acceptedFileTypes;
706
+ }
707
+ else {
708
+ this.enableAttachments = false;
709
+ }
710
+ }
536
711
  ngAfterViewChecked() {
537
712
  if (this.scrollToBottom) {
538
713
  this.scrollToBottom = false;
@@ -548,10 +723,11 @@ export class ConversationChatAreaComponent {
548
723
  }
549
724
  }
550
725
  ngOnDestroy() {
726
+ // Complete the destroy$ Subject to clean up subscriptions
727
+ this.destroy$.next();
728
+ this.destroy$.complete();
551
729
  // Stop polling when component is destroyed
552
730
  this.agentStateService.stopPolling();
553
- // Stop agent run update timer
554
- this.stopAgentRunUpdateTimer();
555
731
  // Remove resize listeners
556
732
  window.removeEventListener('mousemove', this.onResizeMove.bind(this));
557
733
  window.removeEventListener('mouseup', this.onResizeEnd.bind(this));
@@ -566,7 +742,6 @@ export class ConversationChatAreaComponent {
566
742
  }
567
743
  // Do NOT clear activeTasks - they are workspace-level and persist across conversations
568
744
  // Clearing causes bugs: global tasks panel blanks out, no notifications when switching
569
- this.previousMessageStatuses.clear();
570
745
  this.showArtifactPanel = false;
571
746
  this.selectedArtifactId = null;
572
747
  if (conversationId) {
@@ -583,6 +758,7 @@ export class ConversationChatAreaComponent {
583
758
  try {
584
759
  await this.loadMessages(conversationId);
585
760
  await this.restoreActiveTasks(conversationId);
761
+ // TODO: Replace polling with PubSub - see plans/repair-conversations-ui-performance.md
586
762
  this.agentStateService.startPolling(this.currentUser, conversationId);
587
763
  }
588
764
  catch (error) {
@@ -683,13 +859,8 @@ export class ConversationChatAreaComponent {
683
859
  messages.push(message);
684
860
  }
685
861
  this.messages = messages;
686
- // Initialize status tracking to detect message completion
687
- this.previousMessageStatuses.clear();
688
- for (const message of messages) {
689
- if (message.ID && message.Status) {
690
- this.previousMessageStatuses.set(message.ID, message.Status);
691
- }
692
- }
862
+ // Update attachment support based on agents in this conversation
863
+ this.updateAttachmentSupport();
693
864
  // Detect in-progress messages for streaming reconnection
694
865
  // Always create NEW array reference to trigger Input setter in message-input component
695
866
  this.inProgressMessageIds = [...messages
@@ -697,7 +868,25 @@ export class ConversationChatAreaComponent {
697
868
  .map(m => m.ID)];
698
869
  if (this.inProgressMessageIds.length > 0) {
699
870
  LogStatusEx({ message: `🔌 Detected ${this.inProgressMessageIds.length} in-progress messages for reconnection`, verboseOnly: true });
700
- this.startAgentRunUpdateTimer();
871
+ // Check for missed completions - handle the "navigate away then back" scenario
872
+ // The streaming service caches recent completions for components that initialize late
873
+ for (const message of messages) {
874
+ if (message.Status === 'In-Progress' && message.ID) {
875
+ const recentCompletion = this.streamingService.getRecentCompletion(message.ID);
876
+ if (recentCompletion) {
877
+ LogStatusEx({ message: `🔄 Found missed completion for message ${message.ID}, processing...`, verboseOnly: true });
878
+ // Process the completion asynchronously (don't await to avoid blocking)
879
+ this.handleMessageCompletion(message, recentCompletion.agentRunId)
880
+ .then(() => {
881
+ // Clear the cached completion after handling
882
+ this.streamingService.clearRecentCompletion(message.ID);
883
+ })
884
+ .catch(error => {
885
+ console.error(`Failed to handle missed completion for message ${message.ID}:`, error);
886
+ });
887
+ }
888
+ }
889
+ }
701
890
  }
702
891
  this.scrollToBottom = true;
703
892
  LogStatusEx({ message: `✅ Built ${messages.length} messages from cache`, verboseOnly: true });
@@ -737,12 +926,12 @@ export class ConversationChatAreaComponent {
737
926
  async loadPeripheralData(conversationId) {
738
927
  const timestamp = new Date().toISOString();
739
928
  // Skip if we've already processed peripheral data for this conversation
740
- if (this.lastLoadedConversationId === conversationId) {
929
+ if (this.loadedPeripheralConversationIds.has(conversationId)) {
741
930
  LogStatusEx({ message: `[${timestamp}] ⏭️ Skipping peripheral data processing - already processed for conversation ${conversationId}`, verboseOnly: true });
742
931
  return;
743
932
  }
744
933
  // Mark this conversation as processed to prevent duplicate processing
745
- this.lastLoadedConversationId = conversationId;
934
+ this.loadedPeripheralConversationIds.add(conversationId);
746
935
  LogStatusEx({ message: `[${timestamp}] 📊 Processing peripheral data for conversation ${conversationId} from cache`, verboseOnly: true });
747
936
  try {
748
937
  // Get cached data - should always be present by the time we get here
@@ -806,9 +995,18 @@ export class ConversationChatAreaComponent {
806
995
  this.systemArtifactsByDetailId.set(row.ID, systemArtifactList);
807
996
  }
808
997
  }
809
- // Build ratings map
810
- if (parsed.ratings.length > 0) {
811
- this.ratingsByDetailId.set(row.ID, parsed.ratings);
998
+ // Build ratings map - always set (empty array if no ratings)
999
+ // This tells the rating component not to query the database
1000
+ this.ratingsByDetailId.set(row.ID, parsed.ratings);
1001
+ }
1002
+ // Load attachments for all messages in this conversation
1003
+ // Uses the ConversationAttachmentService to batch-load all attachments
1004
+ this.attachmentsByDetailId.clear();
1005
+ const messageIds = conversationData.map(row => row.ID).filter((id) => !!id);
1006
+ if (messageIds.length > 0) {
1007
+ const attachmentsMap = await this.attachmentService.loadAttachmentsForMessages(messageIds, this.currentUser);
1008
+ for (const [detailId, attachments] of attachmentsMap) {
1009
+ this.attachmentsByDetailId.set(detailId, attachments);
812
1010
  }
813
1011
  }
814
1012
  // Create new Map references to trigger Angular change detection
@@ -816,13 +1014,15 @@ export class ConversationChatAreaComponent {
816
1014
  this.artifactsByDetailId = new Map(this.artifactsByDetailId);
817
1015
  this.ratingsByDetailId = new Map(this.ratingsByDetailId);
818
1016
  this.systemArtifactsByDetailId = new Map(this.systemArtifactsByDetailId);
1017
+ this.attachmentsByDetailId = new Map(this.attachmentsByDetailId);
819
1018
  // Clear combined cache since we loaded new artifacts
820
1019
  this._combinedArtifactsMap = null;
821
1020
  // Update artifact count for header display (unique artifacts, not versions)
822
1021
  this.artifactCount = this.calculateUniqueArtifactCount();
823
1022
  // Debug: Log summary
824
1023
  const systemArtifactCount = this.systemArtifactsByDetailId.size;
825
- LogStatusEx({ message: `📊 Processed ${this.agentRunsByDetailId.size} agent runs, ${this.artifactsByDetailId.size} user artifact mappings, ${systemArtifactCount} system artifact mappings (${this.artifactCount} unique user artifacts)`, verboseOnly: true });
1024
+ const attachmentCount = this.attachmentsByDetailId.size;
1025
+ LogStatusEx({ message: `📊 Processed ${this.agentRunsByDetailId.size} agent runs, ${this.artifactsByDetailId.size} user artifact mappings, ${systemArtifactCount} system artifact mappings (${this.artifactCount} unique user artifacts), ${attachmentCount} messages with attachments`, verboseOnly: true });
826
1026
  // CRITICAL: Trigger message re-render now that agent runs and artifacts are loaded
827
1027
  // This updates all message components with the newly loaded agent run data
828
1028
  this.messages = [...this.messages]; // Create new array reference to trigger change detection
@@ -831,8 +1031,8 @@ export class ConversationChatAreaComponent {
831
1031
  }
832
1032
  catch (error) {
833
1033
  console.error('Failed to process peripheral data:', error);
834
- // Don't set lastLoadedConversationId on error so we can retry
835
- this.lastLoadedConversationId = null;
1034
+ // Remove from loaded set on error so we can retry
1035
+ this.loadedPeripheralConversationIds.delete(conversationId);
836
1036
  }
837
1037
  }
838
1038
  /**
@@ -844,7 +1044,7 @@ export class ConversationChatAreaComponent {
844
1044
  // Intentionally empty - ActiveTasksService only tracks in-memory running tasks
845
1045
  // Database tasks are loaded separately by TasksDropdownComponent
846
1046
  }
847
- onMessageSent(message) {
1047
+ async onMessageSent(message) {
848
1048
  // Clear pending message if it was sent - notify parent via output
849
1049
  if (this.pendingMessage) {
850
1050
  this.pendingMessageConsumed.emit();
@@ -865,10 +1065,37 @@ export class ConversationChatAreaComponent {
865
1065
  this.messages = [...this.messages, message];
866
1066
  // Ensure current user is in the avatar map for new messages
867
1067
  this.ensureCurrentUserInAvatarMap();
1068
+ // Invalidate cache when new message is added.
1069
+ // Without this, navigating away and back would load stale cached data
1070
+ // that doesn't include this new message.
1071
+ if (this.conversationId) {
1072
+ this.invalidateConversationCache(this.conversationId);
1073
+ }
1074
+ // Load attachments for the new message (if any were saved with it)
1075
+ // This ensures attachments are displayed immediately after sending
1076
+ await this.loadAttachmentsForMessage(message.ID);
868
1077
  }
869
1078
  // Scroll to bottom when new message is sent
870
1079
  this.scrollToBottom = true;
871
1080
  }
1081
+ /**
1082
+ * Loads attachments for a single message and adds them to the attachmentsByDetailId map.
1083
+ * Called after a new message is sent to ensure attachments are displayed immediately.
1084
+ */
1085
+ async loadAttachmentsForMessage(messageId) {
1086
+ try {
1087
+ const attachments = await this.attachmentService.loadAttachmentsForMessage(messageId, this.currentUser);
1088
+ if (attachments.length > 0) {
1089
+ this.attachmentsByDetailId.set(messageId, attachments);
1090
+ // Create new map reference to trigger Angular change detection
1091
+ this.attachmentsByDetailId = new Map(this.attachmentsByDetailId);
1092
+ LogStatusEx({ message: `Loaded ${attachments.length} attachment(s) for message ${messageId}`, verboseOnly: true });
1093
+ }
1094
+ }
1095
+ catch (error) {
1096
+ console.warn('Failed to load attachments for message:', error);
1097
+ }
1098
+ }
872
1099
  /**
873
1100
  * Ensures the current user is in the avatar map
874
1101
  * Called when new messages are created to ensure avatar data is available
@@ -909,8 +1136,57 @@ export class ConversationChatAreaComponent {
909
1136
  // Trigger re-render to show updated status
910
1137
  this.messages = [...this.messages];
911
1138
  this.cdr.detectChanges();
912
- // Stop timer since agent completed
913
- this.stopAgentRunUpdateTimer();
1139
+ }
1140
+ }
1141
+ /**
1142
+ * Handle message completion from PubSub streaming service.
1143
+ * This is the primary completion handler that replaces timer-based polling.
1144
+ * Called when the streaming service receives a completion event from the backend.
1145
+ *
1146
+ * @param message The message entity that completed
1147
+ * @param agentRunId The agent run ID from the completion event
1148
+ */
1149
+ async handleMessageCompletion(message, agentRunId) {
1150
+ try {
1151
+ LogStatusEx({ message: `🔄 Handling completion for message ${message.ID}`, verboseOnly: true });
1152
+ // 1. Reload message from database to get final content
1153
+ await message.Load(message.ID);
1154
+ // 2. Reload agent run to get final status/timestamps
1155
+ const agentRun = this.agentRunsByDetailId.get(message.ID);
1156
+ if (agentRun?.ID) {
1157
+ await agentRun.Load(agentRun.ID);
1158
+ }
1159
+ // 3. Reload artifacts for this completed message
1160
+ await this.reloadArtifactsForMessage(message.ID);
1161
+ // 4. Reload messages to discover newly delegated agent messages
1162
+ // When Sage delegates to Marketing Agent, a new message is created
1163
+ await this.reloadMessagesForActiveConversation();
1164
+ // 5. Update inProgressMessageIds to track any new delegated agents
1165
+ this.inProgressMessageIds = [...this.messages
1166
+ .filter(m => m.Status === 'In-Progress')
1167
+ .map(m => m.ID)];
1168
+ // 6. Auto-open artifact panel if message has artifacts and no artifact is currently shown
1169
+ if (this.artifactsByDetailId.has(message.ID) && !this.showArtifactPanel) {
1170
+ const artifactList = this.artifactsByDetailId.get(message.ID);
1171
+ if (artifactList && artifactList.length > 0) {
1172
+ // Show the LAST (most recent) artifact
1173
+ this.selectedArtifactId = artifactList[artifactList.length - 1].artifactId;
1174
+ this.showArtifactPanel = true;
1175
+ await this.loadArtifactPermissions(this.selectedArtifactId);
1176
+ }
1177
+ }
1178
+ // 7. Remove task from ActiveTasksService (clears spinner in conversation list)
1179
+ const task = this.activeTasks.getByConversationDetailId(message.ID);
1180
+ if (task) {
1181
+ this.activeTasks.remove(task.id);
1182
+ }
1183
+ // 8. Trigger re-render with updated data
1184
+ this.messages = [...this.messages];
1185
+ this.cdr.detectChanges();
1186
+ LogStatusEx({ message: `✅ Completion handled for message ${message.ID}`, verboseOnly: true });
1187
+ }
1188
+ catch (error) {
1189
+ console.error(`Failed to handle completion for message ${message.ID}:`, error);
914
1190
  }
915
1191
  }
916
1192
  /**
@@ -919,75 +1195,19 @@ export class ConversationChatAreaComponent {
919
1195
  * Provides real-time updates of status, timestamps, tokens, cost during execution
920
1196
  */
921
1197
  async onAgentRunUpdate(event) {
922
- let run;
923
1198
  if (event.agentRun) {
924
1199
  // Directly update map with fresh data from progress (no database query needed)
925
1200
  // Don't create new Map - message-list component needs to keep the same reference
926
1201
  this.agentRunsByDetailId.set(event.conversationDetailId, event.agentRun);
927
- run = event.agentRun;
928
1202
  }
929
1203
  else {
930
1204
  // no agent run, should have agentRunId
931
- run = await this.addAgentRunToMap(event.conversationDetailId, event.agentRunId);
1205
+ await this.addAgentRunToMap(event.conversationDetailId, event.agentRunId);
932
1206
  }
933
1207
  // Force message list to re-render with updated agent run
934
1208
  // This ensures message components receive the fresh agent run data
935
1209
  this.messages = [...this.messages];
936
1210
  this.cdr.detectChanges();
937
- // Start 1-second update timer for smooth UI updates (if not already running)
938
- this.startAgentRunUpdateTimer();
939
- // If agent completed or failed, stop the timer
940
- const status = run.Status?.toLowerCase();
941
- if (status === 'complete' || status === 'completed' || status === 'failed' || status === 'error') {
942
- this.stopAgentRunUpdateTimer();
943
- }
944
- }
945
- /**
946
- * Start 1-second timer for smooth agent run UI updates
947
- * Updates the message list every second to keep elapsed times current
948
- * Also detects when messages complete and reloads agent runs
949
- */
950
- startAgentRunUpdateTimer() {
951
- // Don't start if already running
952
- if (this.agentRunUpdateTimer !== null) {
953
- return;
954
- }
955
- LogStatusEx({ message: '⏱️ Starting agent run update timer (1-second interval)', verboseOnly: true });
956
- this.agentRunUpdateTimer = setInterval(async () => {
957
- // Check for messages that changed from In-Progress to Complete
958
- // This handles the navigation scenario where onMessageComplete isn't called
959
- await this.detectAndHandleCompletedMessages();
960
- // Check if we have any active agent runs
961
- let hasActiveRuns = false;
962
- for (const agentRun of this.agentRunsByDetailId.values()) {
963
- const status = agentRun.Status?.toLowerCase();
964
- if (status === 'in-progress' || status === 'running') {
965
- hasActiveRuns = true;
966
- break;
967
- }
968
- }
969
- // Keep timer running if we have active runs OR tracking messages for completion
970
- // This ensures we detect completions even before agent runs are fully loaded
971
- if (hasActiveRuns || this.previousMessageStatuses.size > 0) {
972
- // Force message list to re-render so timers update
973
- this.messages = [...this.messages];
974
- this.cdr.detectChanges();
975
- }
976
- else {
977
- // Stop only if nothing to monitor
978
- this.stopAgentRunUpdateTimer();
979
- }
980
- }, 1000);
981
- }
982
- /**
983
- * Stop the agent run update timer
984
- */
985
- stopAgentRunUpdateTimer() {
986
- if (this.agentRunUpdateTimer !== null) {
987
- LogStatusEx({ message: '⏹️ Stopping agent run update timer', verboseOnly: true });
988
- clearInterval(this.agentRunUpdateTimer);
989
- this.agentRunUpdateTimer = null;
990
- }
991
1211
  }
992
1212
  /**
993
1213
  * Reload messages for the active conversation from the database
@@ -1038,68 +1258,6 @@ export class ConversationChatAreaComponent {
1038
1258
  console.error('Failed to reload messages for active conversation:', error);
1039
1259
  }
1040
1260
  }
1041
- /**
1042
- * Detect messages that changed from In-Progress to Complete and reload their agent runs
1043
- * This handles the navigation scenario where onMessageComplete event isn't fired
1044
- */
1045
- async detectAndHandleCompletedMessages() {
1046
- try {
1047
- for (const message of this.messages) {
1048
- if (!message.ID)
1049
- continue;
1050
- const currentStatus = message.Status;
1051
- const previousStatus = this.previousMessageStatuses.get(message.ID);
1052
- // Detect completion: was In-Progress, now Complete
1053
- if (previousStatus === 'In-Progress' && currentStatus === 'Complete') {
1054
- // Get the agent run for this message
1055
- const agentRun = this.agentRunsByDetailId.get(message.ID);
1056
- if (agentRun?.ID) {
1057
- try {
1058
- // Reload agent run from database to get updated Status
1059
- await agentRun.Load(agentRun.ID);
1060
- // Reload artifacts for this completed message
1061
- await this.reloadArtifactsForMessage(message.ID);
1062
- // CRITICAL: Reload messages to pick up newly delegated agent messages
1063
- // When Sage delegates to Marketing Agent, a new message is created
1064
- // We need to discover and register callbacks for these new messages
1065
- await this.reloadMessagesForActiveConversation();
1066
- // Update inProgressMessageIds to include new delegated agents
1067
- // This triggers callback registration via the setter in message-input
1068
- this.inProgressMessageIds = [...this.messages
1069
- .filter(m => m.Status === 'In-Progress')
1070
- .map(m => m.ID)];
1071
- // Auto-open artifact panel if this message has artifacts and no artifact is currently shown
1072
- if (this.artifactsByDetailId.has(message.ID) && !this.showArtifactPanel) {
1073
- const artifactList = this.artifactsByDetailId.get(message.ID);
1074
- if (artifactList && artifactList.length > 0) {
1075
- // Show the LAST (most recent) artifact - uses display data, no lazy load needed
1076
- this.selectedArtifactId = artifactList[artifactList.length - 1].artifactId;
1077
- this.showArtifactPanel = true;
1078
- // Load permissions for the new artifact
1079
- await this.loadArtifactPermissions(this.selectedArtifactId);
1080
- }
1081
- }
1082
- // Force re-render with updated agent run and artifacts
1083
- this.messages = [...this.messages];
1084
- this.cdr.detectChanges();
1085
- // IMPORTANT: Remove from tracking map so timer can stop when all messages complete
1086
- this.previousMessageStatuses.delete(message.ID);
1087
- }
1088
- catch (error) {
1089
- console.error('Failed to reload agent run on completion:', error);
1090
- }
1091
- }
1092
- }
1093
- else if (currentStatus === 'In-Progress') {
1094
- // Only track In-Progress messages - don't re-add Complete messages
1095
- this.previousMessageStatuses.set(message.ID, currentStatus);
1096
- }
1097
- }
1098
- }
1099
- catch (error) {
1100
- console.error('Error in detectAndHandleCompletedMessages:', error);
1101
- }
1102
- }
1103
1261
  async onAgentResponse(event) {
1104
1262
  // Add the agent's response message to the conversation
1105
1263
  this.messages = [...this.messages, event.message];
@@ -1137,6 +1295,7 @@ export class ConversationChatAreaComponent {
1137
1295
  */
1138
1296
  invalidateConversationCache(conversationId) {
1139
1297
  this.conversationDataCache.delete(conversationId);
1298
+ this.loadedPeripheralConversationIds.delete(conversationId);
1140
1299
  LogStatusEx({ message: `🗑️ Invalidated cache for conversation ${conversationId}`, verboseOnly: true });
1141
1300
  }
1142
1301
  /**
@@ -1474,7 +1633,7 @@ export class ConversationChatAreaComponent {
1474
1633
  else if (!this.conversation || this.isNewConversation) {
1475
1634
  // If no conversation or in new unsaved state, route through empty state handler
1476
1635
  // This will create the conversation and send the message
1477
- await this.onEmptyStateMessageSent(messageText);
1636
+ await this.onEmptyStateMessageSent({ text: messageText, attachments: [] });
1478
1637
  }
1479
1638
  else {
1480
1639
  console.error('MessageInputComponent not available and not in a valid state to create conversation');
@@ -1486,6 +1645,37 @@ export class ConversationChatAreaComponent {
1486
1645
  LogStatusEx({ message: 'Retry requested for message', verboseOnly: true, additionalArgs: [message.ID] });
1487
1646
  // For now, just log it - full implementation would require refactoring agent invocation
1488
1647
  }
1648
+ /**
1649
+ * Handle attachment click - opens the image viewer for images
1650
+ */
1651
+ onAttachmentClicked(attachment) {
1652
+ if (attachment.type === 'Image' && attachment.contentUrl) {
1653
+ this.selectedImageUrl = attachment.contentUrl;
1654
+ this.selectedImageAlt = attachment.fileName || 'Image attachment';
1655
+ this.selectedImageFileName = attachment.fileName || 'image';
1656
+ this.showImageViewer = true;
1657
+ }
1658
+ else {
1659
+ // For non-image attachments, could trigger download or other action
1660
+ console.log('Non-image attachment clicked:', attachment);
1661
+ }
1662
+ }
1663
+ /**
1664
+ * Handle image viewer close
1665
+ */
1666
+ onImageViewerClosed() {
1667
+ this.showImageViewer = false;
1668
+ this.selectedImageUrl = '';
1669
+ this.selectedImageAlt = '';
1670
+ this.selectedImageFileName = '';
1671
+ }
1672
+ /**
1673
+ * Handle upload state changes from message input component
1674
+ */
1675
+ onUploadStateChanged(event) {
1676
+ this.isUploadingAttachments = event.isUploading;
1677
+ this.uploadingMessage = event.message;
1678
+ }
1489
1679
  async onArtifactClicked(data) {
1490
1680
  this.selectedArtifactId = data.artifactId;
1491
1681
  // If versionId is provided, find the version number from display data (no lazy load needed)
@@ -1699,30 +1889,36 @@ export class ConversationChatAreaComponent {
1699
1889
  * Handle message sent from empty state component
1700
1890
  * Creates a new conversation and emits to parent to update selection
1701
1891
  */
1702
- async onEmptyStateMessageSent(messageText) {
1703
- if (!messageText || !messageText.trim()) {
1892
+ async onEmptyStateMessageSent(event) {
1893
+ const { text, attachments } = event;
1894
+ if (!text?.trim() && (!attachments || attachments.length === 0)) {
1704
1895
  return;
1705
1896
  }
1706
- LogStatusEx({ message: '📨 Empty state message received', verboseOnly: true, additionalArgs: [messageText] });
1897
+ LogStatusEx({ message: '📨 Empty state message received', verboseOnly: true, additionalArgs: [text, `${attachments?.length || 0} attachments`] });
1707
1898
  try {
1708
1899
  this.isProcessing = true;
1709
1900
  // Create a new conversation using the data service
1710
1901
  const newConversation = await this.conversationData.createConversation('New Conversation', // Temporary name - will be auto-named after first message
1711
1902
  this.environmentId, this.currentUser);
1712
1903
  if (!newConversation) {
1713
- console.error('Failed to create new conversation');
1904
+ console.error('Failed to create new conversation');
1714
1905
  this.isProcessing = false;
1715
1906
  return;
1716
1907
  }
1717
1908
  LogStatusEx({ message: '✅ Created new conversation', verboseOnly: true, additionalArgs: [newConversation.ID] });
1718
- // Emit to parent with the new conversation AND the pending message
1719
- // Parent will update its state and pass back the message via pendingMessage input
1720
- this.conversationCreated.emit(newConversation);
1721
- // Also emit the pending message to be sent (parent will pass it back via input)
1722
- this.pendingMessageRequested.emit(messageText.trim());
1909
+ // Emit to parent with the new conversation AND the pending message/attachments in a single event
1910
+ // This ensures atomic state update - workspace sets all state before Angular change detection
1911
+ // creates the new message-input component
1912
+ const pendingMessage = text?.trim() || '';
1913
+ const pendingAttachments = attachments || [];
1914
+ this.conversationCreated.emit({
1915
+ conversation: newConversation,
1916
+ pendingMessage,
1917
+ pendingAttachments
1918
+ });
1723
1919
  }
1724
1920
  catch (error) {
1725
- console.error('Error creating conversation from empty state:', error);
1921
+ console.error('Error creating conversation from empty state:', error);
1726
1922
  }
1727
1923
  finally {
1728
1924
  this.isProcessing = false;
@@ -2003,7 +2199,7 @@ export class ConversationChatAreaComponent {
2003
2199
  this.cdr.detectChanges();
2004
2200
  }
2005
2201
  }
2006
- static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationDataService), i0.ɵɵdirectiveInject(i2.AgentStateService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.MentionAutocompleteService), i0.ɵɵdirectiveInject(i6.ArtifactPermissionService), i0.ɵɵdirectiveInject(i7.DialogService)); };
2202
+ static ɵfac = function ConversationChatAreaComponent_Factory(t) { return new (t || ConversationChatAreaComponent)(i0.ɵɵdirectiveInject(i1.ConversationDataService), i0.ɵɵdirectiveInject(i2.AgentStateService), i0.ɵɵdirectiveInject(i3.ConversationAgentService), i0.ɵɵdirectiveInject(i4.ActiveTasksService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.MentionAutocompleteService), i0.ɵɵdirectiveInject(i6.ArtifactPermissionService), i0.ɵɵdirectiveInject(i7.DialogService), i0.ɵɵdirectiveInject(i8.ConversationAttachmentService), i0.ɵɵdirectiveInject(i9.ConversationStreamingService)); };
2007
2203
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ConversationChatAreaComponent, selectors: [["mj-conversation-chat-area"]], viewQuery: function ConversationChatAreaComponent_Query(rf, ctx) { if (rf & 1) {
2008
2204
  i0.ɵɵviewQuery(_c0, 5);
2009
2205
  i0.ɵɵviewQuery(ArtifactViewerPanelComponent, 5);
@@ -2013,11 +2209,11 @@ export class ConversationChatAreaComponent {
2013
2209
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.scrollContainer = _t.first);
2014
2210
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.artifactViewerComponent = _t.first);
2015
2211
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.messageInputComponents = _t);
2016
- } }, inputs: { environmentId: "environmentId", currentUser: "currentUser", conversationId: "conversationId", conversation: "conversation", threadId: "threadId", isNewConversation: "isNewConversation", pendingMessage: "pendingMessage", pendingArtifactId: "pendingArtifactId", pendingArtifactVersionNumber: "pendingArtifactVersionNumber" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked", conversationCreated: "conversationCreated", threadOpened: "threadOpened", threadClosed: "threadClosed", pendingArtifactConsumed: "pendingArtifactConsumed", pendingMessageConsumed: "pendingMessageConsumed", pendingMessageRequested: "pendingMessageRequested" }, decls: 15, vars: 20, consts: [["scrollContainer", ""], ["messageInput", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [3, "currentUser", "disabled"], [1, "conversation-loading-state"], [1, "chat-messages-wrapper"], [1, "chat-artifact-pane", 3, "width", "maximized"], [3, "saved", "cancelled", "isOpen", "artifact", "currentUser"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "isVisible", "conversation", "currentUser"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds"], [1, "chat-header"], [1, "chat-info"], [1, "chat-title"], ["class", "project-tag", "title", "Assign to project", 3, "click", 4, "ngIf"], ["class", "test-indicator", "title", "View Test Run", 3, "click", 4, "ngIf"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions"], ["title", "View members", 1, "chat-members", 3, "click"], [1, "fas", "fa-users"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "action-btn", "share-btn", 3, "click", "title"], [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 artifacts", 1, "artifact-indicator", 3, "click"], [1, "fas", "fa-cube"], [3, "messageSent", "currentUser", "disabled"], ["text", "Loading conversation...", "size", "large"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap"], ["class", "scroll-to-bottom-icon", "style", "left: 50%;", 3, "click", 4, "ngIf"], [1, "chat-input-container"], [1, "loading-peripheral-placeholder"], [1, "message-input-container-wrapper"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], ["text", "Loading conversation data...", "size", "medium"], [3, "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "initialMessage"], [3, "messageSent", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "initialMessage"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "openEntityRecord", "artifactId", "currentUser", "environmentId", "versionNumber", "viewContext", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [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"], [1, "empty-state"], [1, "artifact-modal-card", 3, "expanded", "system-artifact"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "click"], [1, "fas", "fa-cog"], [1, "fas", "fa-cube", 2, "font-size", "48px", "color", "#D1D5DB", "margin-bottom", "16px"], [2, "color", "#6B7280", "font-size", "14px"], [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, "saved", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
2212
+ } }, inputs: { environmentId: "environmentId", currentUser: "currentUser", conversationId: "conversationId", conversation: "conversation", threadId: "threadId", isNewConversation: "isNewConversation", pendingMessage: "pendingMessage", pendingAttachments: "pendingAttachments", pendingArtifactId: "pendingArtifactId", pendingArtifactVersionNumber: "pendingArtifactVersionNumber", showSidebarToggle: "showSidebarToggle" }, outputs: { conversationRenamed: "conversationRenamed", openEntityRecord: "openEntityRecord", taskClicked: "taskClicked", artifactLinkClicked: "artifactLinkClicked", sidebarToggleClicked: "sidebarToggleClicked", conversationCreated: "conversationCreated", threadOpened: "threadOpened", threadClosed: "threadClosed", pendingArtifactConsumed: "pendingArtifactConsumed", pendingMessageConsumed: "pendingMessageConsumed", pendingMessageRequested: "pendingMessageRequested" }, decls: 16, vars: 21, consts: [["scrollContainer", ""], ["messageInput", ""], [1, "chat-area"], ["class", "chat-header", 4, "ngIf"], [1, "chat-content-area"], [1, "chat-messages-pane"], [3, "currentUser", "disabled", "showSidebarToggle"], [1, "conversation-loading-state"], [1, "chat-messages-wrapper"], [1, "chat-artifact-pane", 3, "width", "maximized"], [3, "saved", "cancelled", "isOpen", "artifact", "currentUser"], [3, "parentMessageId", "conversationId", "currentUser"], [3, "cancelled", "exported", "isVisible", "conversation", "currentUser"], [3, "cancelled", "membersChanged", "isVisible", "conversation", "currentUser"], [1, "modal-overlay"], [3, "isOpen", "environmentId", "currentUser", "excludeCollectionIds"], [3, "imageUrl", "alt", "fileName", "visible"], [1, "chat-header"], [1, "chat-info"], ["class", "sidebar-toggle-btn", "title", "Show conversations", 3, "click", 4, "ngIf"], [1, "chat-title"], ["class", "project-tag", "title", "Assign to project", 3, "click", 4, "ngIf"], ["class", "test-indicator", "title", "View Test Run", 3, "click", 4, "ngIf"], [3, "togglePanel", "agentSelected", "conversationId", "currentUser"], [1, "chat-actions", "chat-actions-buttons"], ["class", "artifact-indicator", "title", "View artifacts", 3, "click", 4, "ngIf"], ["class", "chat-members", "title", "View members", 3, "click", 4, "ngIf"], ["title", "Export conversation", 1, "action-btn", 3, "click"], [1, "fas", "fa-download"], [1, "btn-label"], [1, "action-btn", "share-btn", 3, "click", "title"], [1, "fas", "fa-share-nodes"], ["title", "Show conversations", 1, "sidebar-toggle-btn", 3, "click"], [1, "fas", "fa-table-columns"], ["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 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, "sidebarToggleClicked", "messageSent", "currentUser", "disabled", "showSidebarToggle"], ["text", "Loading conversation...", "size", "large"], [1, "upload-indicator-overlay"], [1, "chat-messages-container", 3, "scroll"], [3, "replyInThread", "viewThread", "retryMessage", "testFeedbackMessage", "artifactClicked", "messageEdited", "openEntityRecord", "suggestedResponseSelected", "attachmentClicked", "messages", "conversation", "currentUser", "isProcessing", "artifactMap", "agentRunMap", "ratingsMap", "userAvatarMap", "attachmentsMap"], ["class", "scroll-to-bottom-icon", "style", "left: 50%;", 3, "click", 4, "ngIf"], [1, "chat-input-container"], [1, "loading-peripheral-placeholder"], [1, "message-input-container-wrapper"], ["size", "medium", 3, "text"], [1, "scroll-to-bottom-icon", 2, "left", "50%", 3, "click"], [1, "fas", "fa-arrow-down"], ["text", "Loading conversation data...", "size", "medium"], [3, "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [3, "messageSent", "agentResponse", "agentRunDetected", "agentRunUpdate", "messageComplete", "artifactCreated", "conversationRenamed", "intentCheckStarted", "intentCheckCompleted", "uploadStateChanged", "hidden", "conversationId", "conversationName", "currentUser", "conversationHistory", "artifactsByDetailId", "systemArtifactsByDetailId", "agentRunsByDetailId", "inProgressMessageIds", "disabled", "enableAttachments", "maxAttachments", "maxAttachmentSizeBytes", "acceptedFileTypes", "initialMessage", "initialAttachments"], [1, "resize-handle"], [1, "chat-artifact-pane"], [3, "closed", "saveToCollectionRequested", "navigateToLink", "shareRequested", "maximizeToggled", "openEntityRecord", "artifactId", "currentUser", "environmentId", "versionNumber", "viewContext", "canShare", "canEdit", "isMaximized", "refreshTrigger"], [1, "resize-handle", 3, "mousedown", "touchstart"], [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"], [1, "empty-state"], [1, "artifact-modal-card", 3, "expanded", "system-artifact"], ["title", "Toggle system artifacts visibility", 1, "toggle-system-btn", 3, "click"], [1, "fas", "fa-cog"], [1, "fas", "fa-cube", 2, "font-size", "48px", "color", "#D1D5DB", "margin-bottom", "16px"], [2, "color", "#6B7280", "font-size", "14px"], [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, "saved", "cancelled", "isOpen", "environmentId", "currentUser", "excludeCollectionIds"], [3, "closed", "imageUrl", "alt", "fileName", "visible"]], template: function ConversationChatAreaComponent_Template(rf, ctx) { if (rf & 1) {
2017
2213
  i0.ɵɵelementStart(0, "div", 2);
2018
- i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 21, 13, "div", 3);
2214
+ i0.ɵɵtemplate(1, ConversationChatAreaComponent_div_1_Template, 20, 15, "div", 3);
2019
2215
  i0.ɵɵelementStart(2, "div", 4)(3, "div", 5);
2020
- i0.ɵɵtemplate(4, ConversationChatAreaComponent_Conditional_4_Template, 1, 2, "mj-conversation-empty-state", 6)(5, ConversationChatAreaComponent_Conditional_5_Template, 2, 0, "div", 7)(6, ConversationChatAreaComponent_Conditional_6_Template, 8, 10, "div", 8);
2216
+ i0.ɵɵtemplate(4, ConversationChatAreaComponent_Conditional_4_Template, 1, 3, "mj-conversation-empty-state", 6)(5, ConversationChatAreaComponent_Conditional_5_Template, 2, 0, "div", 7)(6, ConversationChatAreaComponent_Conditional_6_Template, 9, 12, "div", 8);
2021
2217
  i0.ɵɵelementEnd();
2022
2218
  i0.ɵɵtemplate(7, ConversationChatAreaComponent_Conditional_7_Template, 3, 14, "div", 9);
2023
2219
  i0.ɵɵelementStart(8, "mj-artifact-share-modal", 10);
@@ -2030,7 +2226,7 @@ export class ConversationChatAreaComponent {
2030
2226
  i0.ɵɵelementStart(11, "mj-members-modal", 13);
2031
2227
  i0.ɵɵlistener("cancelled", function ConversationChatAreaComponent_Template_mj_members_modal_cancelled_11_listener() { return ctx.showMembersModal = false; })("membersChanged", function ConversationChatAreaComponent_Template_mj_members_modal_membersChanged_11_listener() { return ctx.showMembersModal = false; });
2032
2228
  i0.ɵɵelementEnd();
2033
- i0.ɵɵtemplate(12, ConversationChatAreaComponent_Conditional_12_Template, 9, 3, "div", 14)(13, ConversationChatAreaComponent_Conditional_13_Template, 13, 2, "div", 14)(14, ConversationChatAreaComponent_Conditional_14_Template, 1, 4, "mj-artifact-collection-picker-modal", 15);
2229
+ i0.ɵɵtemplate(12, ConversationChatAreaComponent_Conditional_12_Template, 9, 3, "div", 14)(13, ConversationChatAreaComponent_Conditional_13_Template, 13, 2, "div", 14)(14, ConversationChatAreaComponent_Conditional_14_Template, 1, 4, "mj-artifact-collection-picker-modal", 15)(15, ConversationChatAreaComponent_Conditional_15_Template, 1, 4, "mj-image-viewer", 16);
2034
2230
  } if (rf & 2) {
2035
2231
  i0.ɵɵadvance();
2036
2232
  i0.ɵɵproperty("ngIf", ctx.conversation);
@@ -2054,12 +2250,14 @@ export class ConversationChatAreaComponent {
2054
2250
  i0.ɵɵconditional(ctx.showArtifactsModal ? 13 : -1);
2055
2251
  i0.ɵɵadvance();
2056
2252
  i0.ɵɵconditional(ctx.showCollectionPicker ? 14 : -1);
2057
- } }, dependencies: [i8.NgIf, i9.ArtifactViewerPanelComponent, i10.LoadingComponent, i11.ArtifactCollectionPickerModalComponent, i12.ArtifactShareModalComponent, i13.MessageListComponent, i14.MessageInputComponent, i15.ConversationEmptyStateComponent, i16.ThreadPanelComponent, i17.ProjectSelectorComponent, i18.ActiveAgentIndicatorComponent, i19.MembersModalComponent, i20.ExportModalComponent], 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.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\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.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\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: #D9D9D9;\n border-color: #AAA;\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: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\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: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.chat-members[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.artifact-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\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 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 #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\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: #3B82F6;\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: #FAFAFA;\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}\n\n.chat-messages-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\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: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\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: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\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: rgba(255, 255, 255, 0.5);\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: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\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 #E5E7EB;\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: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\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: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n border-color: #2563EB;\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: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\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.empty-state[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\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: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: #D1D5DB;\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: #9CA3AF;\n background: #F3F4F6;\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: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\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: #F9FAFB;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\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: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\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: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\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: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\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: #F3F4F6;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\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: #6B7280;\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #9333EA;\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: #6B7280;\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #3B82F6;\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: 8px;\n flex-direction: column;\n align-items: stretch;\n }\n .chat-info[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 14px;\n width: 100%;\n white-space: normal;\n }\n .project-tag[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .test-indicator[_ngcontent-%COMP%] {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .chat-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: flex-start;\n width: 100%;\n }\n .chat-members[_ngcontent-%COMP%], \n .artifact-indicator[_ngcontent-%COMP%], \n .action-btn[_ngcontent-%COMP%] {\n padding: 6px 10px;\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: 80px;\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\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: 6px;\n }\n .chat-title[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n .project-tag[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\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 .action-btn[_ngcontent-%COMP%] {\n padding: 4px 8px;\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}"] });
2253
+ i0.ɵɵadvance();
2254
+ i0.ɵɵconditional(ctx.showImageViewer ? 15 : -1);
2255
+ } }, dependencies: [i10.NgIf, i11.ArtifactViewerPanelComponent, i12.LoadingComponent, i13.ArtifactCollectionPickerModalComponent, i14.ArtifactShareModalComponent, i15.MessageListComponent, i16.MessageInputComponent, i17.ConversationEmptyStateComponent, i18.ThreadPanelComponent, i19.ProjectSelectorComponent, i20.ActiveAgentIndicatorComponent, i21.MembersModalComponent, i22.ExportModalComponent, i23.ImageViewerComponent], 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.chat-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\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: rgba(0, 0, 0, 0.08);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #666;\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #333;\n}\n\n.chat-title[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\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: #D9D9D9;\n border-color: #AAA;\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: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\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: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\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 #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members[_ngcontent-%COMP%]:hover, \n.artifact-indicator[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\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: #3B82F6;\n color: white;\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: #6366F1;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\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 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 #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared[_ngcontent-%COMP%] {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n color: #1e3a8a;\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: #3B82F6;\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: #FAFAFA;\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.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: rgba(255, 255, 255, 0.95);\n border-radius: 12px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\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: #FFF;\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: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\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: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.chat-input-container[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\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: rgba(255, 255, 255, 0.5);\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: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content[_ngcontent-%COMP%] {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\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 #E5E7EB;\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: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\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: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%] {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active[_ngcontent-%COMP%]:hover {\n background: #2563EB;\n border-color: #2563EB;\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: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #111827;\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.empty-state[_ngcontent-%COMP%] {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\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: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact[_ngcontent-%COMP%] {\n opacity: 0.85;\n border-color: #D1D5DB;\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: #9CA3AF;\n background: #F3F4F6;\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: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\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: #F9FAFB;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\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: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\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: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action[_ngcontent-%COMP%] {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card[_ngcontent-%COMP%]:hover .artifact-modal-action[_ngcontent-%COMP%] {\n color: #3B82F6;\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: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\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: #F3F4F6;\n}\n.artifact-version-item[_ngcontent-%COMP%] .version-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\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: #6B7280;\n}\n.artifact-version-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-badge[_ngcontent-%COMP%] {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover .version-open-text[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n.artifact-version-item[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #3B82F6;\n}\n\n.loading-peripheral-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: #9333EA;\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: #6B7280;\n font-size: 15px;\n}\n.loading-content[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #3B82F6;\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: #FFF;\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}"] });
2058
2256
  }
2059
2257
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ConversationChatAreaComponent, [{
2060
2258
  type: Component,
2061
- args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversation\">\n <div class=\"chat-info\">\n <div class=\"chat-title\">{{ conversation.Name }}</div>\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" title=\"Assign to project\" *ngIf=\"conversation.ProjectID\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation.Project || 'Project' }}</span>\n </button>\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation.TestRunID)\" title=\"View Test Run\" *ngIf=\"conversation.TestRunID\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\">\n <i class=\"fas fa-users\"></i>\n <span>{{ memberCount }} member{{ memberCount !== 1 ? 's' : '' }}</span>\n </button>\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCountDisplay > 0\">\n <i class=\"fas fa-cube\"></i>\n <span>{{ artifactCountDisplay }} artifact{{ artifactCountDisplay !== 1 ? 's' : '' }}</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions\">\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n Export\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n Share\n </button>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isNewConversation || !conversationId) {\n <!-- Empty State - No conversation selected OR new unsaved conversation -->\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n } @else if (isLoadingConversation) {\n <!-- Loading State - Show centered spinner while conversation loads -->\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\">\n <mj-conversation-message-list\n [messages]=\"messages\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track inputRef.conversationId) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing\"\n [initialMessage]=\"inputRef.conversationId === conversationId ? pendingMessage : null\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted()\"\n (intentCheckCompleted)=\"onIntentCheckCompleted()\">\n </mj-message-input>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Artifact Share Modal -->\n <mj-artifact-share-modal\n [isOpen]=\"isArtifactShareModalOpen\"\n [artifact]=\"artifactToShare\"\n [currentUser]=\"currentUser\"\n (saved)=\"onArtifactShared()\"\n (cancelled)=\"onArtifactShareModalClose()\">\n </mj-artifact-share-modal>\n </div>\n</div>\n\n<!-- Thread Panel -->\n@if (threadId) {\n <mj-thread-panel\n [parentMessageId]=\"threadId\"\n [conversationId]=\"conversationId || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onLocalThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <div class=\"modal-header-actions\">\n @if (hasSystemArtifacts) {\n <button class=\"toggle-system-btn\"\n [class.active]=\"showSystemArtifacts\"\n (click)=\"toggleSystemArtifacts()\"\n title=\"Toggle system artifacts visibility\">\n <i class=\"fas fa-cog\"></i>\n <span>{{ showSystemArtifacts ? 'Hide' : 'Show' }} System</span>\n </button>\n }\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-cube\" style=\"font-size: 48px; color: #D1D5DB; margin-bottom: 16px;\"></i>\n <p style=\"color: #6B7280; font-size: 14px;\">No artifacts in this conversation yet</p>\n </div>\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\"\n [class.expanded]=\"expandedArtifactId === artifact.artifactId\"\n [class.system-artifact]=\"artifact.visibility === 'System Only'\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n (saved)=\"onCollectionPickerSaved($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n.chat-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n\n.project-tag i {\n font-size: 10px;\n}\n\n.test-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator:hover {\n background: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator i {\n font-size: 10px;\n}\n\n.chat-members {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.artifact-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.artifact-indicator:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator i {\n color: #0076B6;\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); /* Respect container bounds while maintaining minimum */\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width {\n width: 100%;\n}\n\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden {\n display: none;\n}\n\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle:hover {\n background: #3B82F6;\n}\n\n.resize-handle::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized {\n width: 100% !important;\n}\n\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn:hover {\n background: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active:hover {\n background: #2563EB;\n border-color: #2563EB;\n}\n\n.toggle-system-btn i {\n font-size: 12px;\n}\n\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n.empty-state {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact {\n opacity: 0.85;\n border-color: #D1D5DB;\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: #9CA3AF;\n background: #F3F4F6;\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact:hover {\n border-color: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header:hover {\n background: #F9FAFB;\n}\n\n.artifact-modal-card:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n\n.artifact-modal-icon i {\n font-size: 18px;\n}\n\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\n}\n\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\n}\n\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item:hover {\n background: #F3F4F6;\n}\n.artifact-version-item .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n}\n.artifact-version-item i {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item:hover .version-badge {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item:hover .version-open-text {\n color: #3B82F6;\n}\n.artifact-version-item:hover i {\n color: #3B82F6;\n}\n\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content i {\n font-size: 20px;\n color: #9333EA;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: #6B7280;\n font-size: 15px;\n}\n.loading-content i {\n font-size: 32px;\n color: #3B82F6;\n}\n.loading-content span {\n font-weight: 500;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .chat-header {\n padding: 8px 12px;\n gap: 8px;\n flex-direction: column;\n align-items: stretch;\n }\n .chat-info {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n .chat-title {\n font-size: 14px;\n width: 100%;\n white-space: normal;\n }\n .project-tag {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n .chat-actions {\n flex-wrap: wrap;\n justify-content: flex-start;\n width: 100%;\n }\n .chat-members,\n .artifact-indicator,\n .action-btn {\n padding: 6px 10px;\n font-size: 12px;\n }\n .ambient-agent-indicator {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal {\n width: min(95vw, 700px);\n }\n .artifacts-grid {\n grid-template-columns: 1fr;\n }\n .chat-input-container {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n /* Artifact pane - full width overlay on mobile */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 80px;\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\n }\n .resize-handle {\n display: none;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .chat-header {\n padding: 6px 8px;\n gap: 6px;\n }\n .chat-title {\n font-size: 13px;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator,\n .action-btn {\n padding: 4px 8px;\n font-size: 11px;\n }\n .ambient-agent-indicator {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal,\n .artifacts-modal {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon i {\n font-size: 14px;\n }\n}\n"] }]
2062
- }], () => [{ type: i1.ConversationDataService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.MentionAutocompleteService }, { type: i6.ArtifactPermissionService }, { type: i7.DialogService }], { environmentId: [{
2259
+ args: [{ selector: 'mj-conversation-chat-area', template: "<div class=\"chat-area\">\n <!-- Fixed Header -->\n <div class=\"chat-header\" *ngIf=\"conversation\">\n <div class=\"chat-info\" [class.with-sidebar-toggle]=\"showSidebarToggle\">\n <button class=\"sidebar-toggle-btn\"\n *ngIf=\"showSidebarToggle\"\n (click)=\"sidebarToggleClicked.emit()\"\n title=\"Show conversations\">\n <i class=\"fas fa-table-columns\"></i>\n </button>\n <div class=\"chat-title\">{{ conversation.Name }}</div>\n <button class=\"project-tag\" (click)=\"openProjectSelector()\" title=\"Assign to project\" *ngIf=\"conversation.ProjectID\">\n <i class=\"fas fa-folder\"></i>\n <span>{{ conversation.Project || 'Project' }}</span>\n </button>\n <button class=\"test-indicator\" (click)=\"viewTestRun(conversation.TestRunID)\" title=\"View Test Run\" *ngIf=\"conversation.TestRunID\">\n <i class=\"fas fa-flask\"></i>\n <span>Test</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n <div class=\"chat-actions chat-actions-buttons\">\n <button class=\"artifact-indicator\" (click)=\"viewArtifacts()\" title=\"View artifacts\" *ngIf=\"artifactCountDisplay > 0\">\n <i class=\"fas fa-cube\"></i>\n <span class=\"artifact-badge\">{{ artifactCountDisplay }}</span>\n </button>\n <button class=\"chat-members\" (click)=\"toggleMembersModal()\" title=\"View members\" *ngIf=\"memberCount > 1\">\n <i class=\"fas fa-users\"></i>\n <span class=\"members-badge\">{{ memberCount }}</span>\n </button>\n <button class=\"action-btn\" (click)=\"exportConversation()\" title=\"Export conversation\">\n <i class=\"fas fa-download\"></i>\n <span class=\"btn-label\">Export</span>\n </button>\n <button class=\"action-btn share-btn\"\n [class.shared]=\"isShared\"\n (click)=\"shareConversation()\"\n [title]=\"isShared ? 'Manage sharing' : 'Share conversation'\">\n <i class=\"fas fa-share-nodes\"></i>\n <span class=\"btn-label\">Share</span>\n </button>\n <mj-active-agent-indicator\n [conversationId]=\"conversation.ID\"\n [currentUser]=\"currentUser\"\n (togglePanel)=\"onToggleAgentPanel()\"\n (agentSelected)=\"onAgentSelected($event)\">\n </mj-active-agent-indicator>\n </div>\n </div>\n\n <!-- Messages and Artifact Split Layout -->\n <div class=\"chat-content-area\">\n <!-- Messages Pane -->\n <div class=\"chat-messages-pane\"\n [class.full-width]=\"!showArtifactPanel\"\n [class.hidden]=\"isArtifactPaneMaximized\">\n @if (isNewConversation || !conversationId) {\n <!-- Empty State - No conversation selected OR new unsaved conversation -->\n <mj-conversation-empty-state\n [currentUser]=\"currentUser\"\n [disabled]=\"isProcessing\"\n [showSidebarToggle]=\"showSidebarToggle\"\n (sidebarToggleClicked)=\"sidebarToggleClicked.emit()\"\n (messageSent)=\"onEmptyStateMessageSent($event)\">\n </mj-conversation-empty-state>\n } @else if (isLoadingConversation) {\n <!-- Loading State - Show centered spinner while conversation loads -->\n <div class=\"conversation-loading-state\">\n <mj-loading text=\"Loading conversation...\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <!-- Normal Message View -->\n <div class=\"chat-messages-wrapper\">\n <!-- Upload Indicator Overlay (centered in conversation area) -->\n @if (isUploadingAttachments) {\n <div class=\"upload-indicator-overlay\">\n <mj-loading [text]=\"uploadingMessage\" size=\"medium\"></mj-loading>\n </div>\n }\n <div class=\"chat-messages-container\" #scrollContainer (scroll)=\"checkScroll()\">\n <mj-conversation-message-list\n [messages]=\"messages\"\n [conversation]=\"conversation\"\n [currentUser]=\"currentUser\"\n [isProcessing]=\"isProcessing\"\n [artifactMap]=\"effectiveArtifactsMap\"\n [agentRunMap]=\"agentRunsByDetailId\"\n [ratingsMap]=\"ratingsByDetailId\"\n [userAvatarMap]=\"userAvatarMap\"\n [attachmentsMap]=\"attachmentsByDetailId\"\n (replyInThread)=\"onReplyInThread($event)\"\n (viewThread)=\"onViewThread($event)\"\n (retryMessage)=\"onRetryMessage($event)\"\n (testFeedbackMessage)=\"onTestFeedbackMessage($event)\"\n (artifactClicked)=\"onArtifactClicked($event)\"\n (messageEdited)=\"onMessageEdited($event)\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\"\n (suggestedResponseSelected)=\"onSuggestedResponseSelected($event)\"\n (attachmentClicked)=\"onAttachmentClicked($event)\">\n </mj-conversation-message-list>\n\n <!-- Scroll to Bottom Icon (positioned within scroll container for proper centering) -->\n <span class=\"scroll-to-bottom-icon\" style=\"left: 50%;\"\n *ngIf=\"showScrollToBottomIcon && messages && messages.length > 0\"\n (click)=\"scrollToBottomAnimate()\">\n <i class=\"fas fa-arrow-down\"></i>\n </span>\n </div>\n\n <!-- Fixed Input Area -->\n <div class=\"chat-input-container\">\n @if (isLoadingPeripheralData) {\n <!-- Loading State -->\n <div class=\"loading-peripheral-placeholder\">\n <mj-loading text=\"Loading conversation data...\" size=\"medium\"></mj-loading>\n </div>\n } @else {\n <!-- Input Component - Multiple instances cached, only one visible -->\n <div class=\"message-input-container-wrapper\">\n @for (inputRef of getCachedInputs(); track inputRef.conversationId) {\n <mj-message-input\n #messageInput\n [hidden]=\"inputRef.conversationId !== conversationId\"\n [conversationId]=\"inputRef.conversationId\"\n [conversationName]=\"inputRef.conversationName\"\n [currentUser]=\"currentUser\"\n [conversationHistory]=\"inputRef.conversationId === conversationId ? messages : []\"\n [artifactsByDetailId]=\"inputRef.conversationId === conversationId ? artifactsByDetailId : emptyArtifactsMap\"\n [systemArtifactsByDetailId]=\"inputRef.conversationId === conversationId ? systemArtifactsByDetailId : emptyArtifactsMap\"\n [agentRunsByDetailId]=\"inputRef.conversationId === conversationId ? agentRunsByDetailId : emptyAgentRunsMap\"\n [inProgressMessageIds]=\"inputRef.conversationId === conversationId ? inProgressMessageIds : emptyInProgressIds\"\n [disabled]=\"isProcessing\"\n [enableAttachments]=\"enableAttachments\"\n [maxAttachments]=\"maxAttachments\"\n [maxAttachmentSizeBytes]=\"maxAttachmentSizeBytes\"\n [acceptedFileTypes]=\"acceptedFileTypes\"\n [initialMessage]=\"inputRef.conversationId === conversationId ? pendingMessage : null\"\n [initialAttachments]=\"inputRef.conversationId === conversationId ? pendingAttachments : null\"\n (messageSent)=\"onMessageSent($event)\"\n (agentResponse)=\"onAgentResponse($event)\"\n (agentRunDetected)=\"onAgentRunDetected($event)\"\n (agentRunUpdate)=\"onAgentRunUpdate($event)\"\n (messageComplete)=\"onMessageComplete($event)\"\n (artifactCreated)=\"onArtifactCreated($event)\"\n (conversationRenamed)=\"onConversationRenamed($event)\"\n (intentCheckStarted)=\"onIntentCheckStarted()\"\n (intentCheckCompleted)=\"onIntentCheckCompleted()\"\n (uploadStateChanged)=\"onUploadStateChanged($event)\">\n </mj-message-input>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Artifact Viewer Pane -->\n @if (showArtifactPanel && selectedArtifactId) {\n @if (!isArtifactPaneMaximized) {\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n }\n <div class=\"chat-artifact-pane\"\n [style.width.%]=\"artifactPaneWidth\"\n [class.maximized]=\"isArtifactPaneMaximized\">\n <mj-artifact-viewer-panel\n [artifactId]=\"selectedArtifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [versionNumber]=\"selectedVersionNumber\"\n [viewContext]=\"'conversation'\"\n [canShare]=\"canShareSelectedArtifact\"\n [canEdit]=\"canEditSelectedArtifact\"\n [isMaximized]=\"isArtifactPaneMaximized\"\n [refreshTrigger]=\"artifactViewerRefresh$\"\n (closed)=\"onCloseArtifactPanel()\"\n (saveToCollectionRequested)=\"onSaveToCollectionRequested($event)\"\n (navigateToLink)=\"onArtifactLinkNavigation($event)\"\n (shareRequested)=\"onArtifactShareRequested($event)\"\n (maximizeToggled)=\"toggleMaximizeArtifactPane()\"\n (openEntityRecord)=\"onOpenEntityRecord($event)\">\n </mj-artifact-viewer-panel>\n </div>\n }\n\n <!-- Artifact Share Modal -->\n <mj-artifact-share-modal\n [isOpen]=\"isArtifactShareModalOpen\"\n [artifact]=\"artifactToShare\"\n [currentUser]=\"currentUser\"\n (saved)=\"onArtifactShared()\"\n (cancelled)=\"onArtifactShareModalClose()\">\n </mj-artifact-share-modal>\n </div>\n</div>\n\n<!-- Thread Panel -->\n@if (threadId) {\n <mj-thread-panel\n [parentMessageId]=\"threadId\"\n [conversationId]=\"conversationId || ''\"\n [currentUser]=\"currentUser\"\n (closed)=\"onLocalThreadClosed()\"\n (replyAdded)=\"onThreadReplyAdded($event)\">\n </mj-thread-panel>\n}\n\n<!-- Export Modal -->\n<mj-export-modal\n [isVisible]=\"showExportModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"onExportModalCancelled()\"\n (exported)=\"onExportModalComplete()\">\n</mj-export-modal>\n\n<!-- Members Modal -->\n<mj-members-modal\n [isVisible]=\"showMembersModal\"\n [conversation]=\"conversation || undefined\"\n [currentUser]=\"currentUser\"\n (cancelled)=\"showMembersModal = false\"\n (membersChanged)=\"showMembersModal = false\">\n</mj-members-modal>\n\n<!-- Project Selector Modal -->\n@if (showProjectSelector && conversation) {\n <div class=\"modal-overlay\" (click)=\"showProjectSelector = false\">\n <div class=\"modal-content project-selector-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Assign Project</h3>\n <button class=\"modal-close-btn\" (click)=\"showProjectSelector = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <mj-project-selector\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [selectedProjectId]=\"conversation.ProjectID\"\n (projectSelected)=\"onProjectSelected($event)\">\n </mj-project-selector>\n </div>\n </div>\n </div>\n}\n\n<!-- Artifacts Modal -->\n@if (showArtifactsModal) {\n <div class=\"modal-overlay\" (click)=\"showArtifactsModal = false\">\n <div class=\"modal-content artifacts-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3>Conversation Artifacts</h3>\n <div class=\"modal-header-actions\">\n @if (hasSystemArtifacts) {\n <button class=\"toggle-system-btn\"\n [class.active]=\"showSystemArtifacts\"\n (click)=\"toggleSystemArtifacts()\"\n title=\"Toggle system artifacts visibility\">\n <i class=\"fas fa-cog\"></i>\n <span>{{ showSystemArtifacts ? 'Hide' : 'Show' }} System</span>\n </button>\n }\n <button class=\"modal-close-btn\" (click)=\"showArtifactsModal = false\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n </div>\n <div class=\"modal-body artifacts-grid\">\n @if (artifactsByDetailId.size === 0) {\n <div class=\"empty-state\">\n <i class=\"fas fa-cube\" style=\"font-size: 48px; color: #D1D5DB; margin-bottom: 16px;\"></i>\n <p style=\"color: #6B7280; font-size: 14px;\">No artifacts in this conversation yet</p>\n </div>\n }\n @for (artifact of getArtifactsArray(); track artifact.artifactId) {\n <div class=\"artifact-modal-card\"\n [class.expanded]=\"expandedArtifactId === artifact.artifactId\"\n [class.system-artifact]=\"artifact.visibility === 'System Only'\">\n <!-- Main card header - click to open latest version -->\n <div class=\"artifact-card-header\" (click)=\"openArtifactFromModal(artifact.artifactId)\">\n <div class=\"artifact-modal-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-modal-info\">\n <div class=\"artifact-modal-title\">{{artifact.name}}</div>\n <div class=\"artifact-modal-meta\">\n @if (artifact.versionCount > 1) {\n {{artifact.versionCount}} versions\n } @else {\n 1 version\n }\n </div>\n </div>\n @if (artifact.versionCount > 1) {\n <button class=\"expand-btn\" (click)=\"toggleArtifactExpansion(artifact.artifactId, $event)\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedArtifactId !== artifact.artifactId\"\n [class.fa-chevron-up]=\"expandedArtifactId === artifact.artifactId\"></i>\n </button>\n }\n <div class=\"artifact-modal-action\">\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n\n <!-- Expanded version list -->\n @if (expandedArtifactId === artifact.artifactId && artifact.versionCount > 1) {\n <div class=\"artifact-versions-list\">\n @for (version of artifact.versions; track version.versionId) {\n <div class=\"artifact-version-item\" (click)=\"openArtifactFromModal(artifact.artifactId, version.versionNumber); $event.stopPropagation()\">\n <span class=\"version-badge\">v{{version.versionNumber}}</span>\n <span class=\"version-open-text\">Open this version</span>\n <i class=\"fas fa-arrow-right\"></i>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n </div>\n}\n\n<!-- Collection Picker Modal -->\n@if (showCollectionPicker) {\n <mj-artifact-collection-picker-modal\n [isOpen]=\"showCollectionPicker\"\n [environmentId]=\"environmentId\"\n [currentUser]=\"currentUser\"\n [excludeCollectionIds]=\"collectionPickerExcludedIds\"\n (saved)=\"onCollectionPickerSaved($event)\"\n (cancelled)=\"onCollectionPickerCancelled()\">\n </mj-artifact-collection-picker-modal>\n}\n\n<!-- Image Viewer Modal -->\n@if (showImageViewer) {\n <mj-image-viewer\n [imageUrl]=\"selectedImageUrl\"\n [alt]=\"selectedImageAlt\"\n [fileName]=\"selectedImageFileName\"\n [visible]=\"showImageViewer\"\n (closed)=\"onImageViewerClosed()\">\n </mj-image-viewer>\n}", styles: [":host {\n display: flex;\n width: 100%;\n height: 100%;\n}\n\n.chat-area {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n.chat-header {\n flex-shrink: 0;\n padding: 12px 20px;\n border-bottom: 1px solid #D9D9D9;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n background: #FFF;\n z-index: 10;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);\n}\n\n.chat-info {\n display: flex;\n align-items: center;\n gap: 12px;\n flex: 1;\n min-width: 0;\n}\n\n/* Sidebar toggle button in header */\n.sidebar-toggle-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n flex-shrink: 0;\n}\n\n.sidebar-toggle-btn:hover {\n background: rgba(0, 0, 0, 0.08);\n}\n\n.sidebar-toggle-btn:active {\n background: rgba(0, 0, 0, 0.12);\n}\n\n.sidebar-toggle-btn i {\n color: #666;\n font-size: 18px;\n transition: color 0.15s ease;\n}\n\n.sidebar-toggle-btn:hover i {\n color: #333;\n}\n\n.chat-title {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.project-tag {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #F4F4F4;\n border: 1px solid #D9D9D9;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #AAA;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 12px;\n}\n\n.project-tag:hover {\n background: #D9D9D9;\n border-color: #AAA;\n}\n\n.project-tag i {\n font-size: 10px;\n}\n\n.test-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: #FFF8E1;\n border: 1px solid #FFD54F;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n color: #F57C00;\n cursor: pointer;\n transition: all 0.2s;\n height: 28px;\n margin-left: 8px;\n}\n\n.test-indicator:hover {\n background: #FFE082;\n border-color: #FFA000;\n}\n\n.test-indicator i {\n font-size: 10px;\n}\n\n.chat-members,\n.artifact-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n padding: 6px 8px;\n background: transparent;\n border: 1px solid #E5E7EB;\n border-radius: 6px;\n font-size: 14px;\n color: #6B7280;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.chat-members:hover,\n.artifact-indicator:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n/* Badge overlay for artifact and member counts */\n.artifact-badge,\n.members-badge {\n position: absolute;\n top: -6px;\n right: -6px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: #3B82F6;\n color: white;\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n.members-badge {\n background: #6366F1;\n}\n\n.ambient-agent-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n background: #F3F4F6;\n border: 1px solid #D1D5DB;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n animation: pulse 2s ease-in-out infinite;\n}\n\n.ambient-agent-indicator i {\n color: #0076B6;\n}\n\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0.7;\n }\n}\n.chat-actions {\n display: flex;\n gap: 8px;\n}\n\n.action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 12px;\n background: transparent;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n border-radius: 6px;\n font-size: 13px;\n color: #6B7280;\n transition: all 150ms ease;\n}\n\n.action-btn:hover {\n background: #F9FAFB;\n color: #111827;\n}\n\n.share-btn.shared {\n background: #EFF6FF;\n border-color: #1e40af;\n color: #1e40af;\n}\n\n.share-btn.shared:hover {\n background: #DBEAFE;\n color: #1e3a8a;\n}\n\n.chat-content-area {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: row;\n position: relative;\n}\n\n.chat-messages-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n min-width: min(300px, 100%); /* Respect container bounds while maintaining minimum */\n overflow: hidden;\n transition: width 0.3s ease;\n}\n\n.chat-messages-pane.full-width {\n width: 100%;\n}\n\n.chat-messages-pane:not(.full-width) {\n flex: 1;\n}\n\n.chat-messages-pane.hidden {\n display: none;\n}\n\n.resize-handle {\n width: 4px;\n background: transparent;\n cursor: col-resize;\n flex-shrink: 0;\n position: relative;\n transition: background-color 0.2s;\n}\n\n.resize-handle:hover {\n background: #3B82F6;\n}\n\n.resize-handle::before {\n content: \"\";\n position: absolute;\n left: -4px;\n right: -4px;\n top: 0;\n bottom: 0;\n}\n\n.chat-artifact-pane {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: #FAFAFA;\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.chat-artifact-pane.maximized {\n width: 100% !important;\n}\n\n.chat-artifact-pane > mj-artifact-viewer-panel {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.chat-messages-wrapper {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-height: 0;\n overflow: hidden;\n position: relative; /* For upload overlay positioning */\n}\n\n/* Upload indicator overlay - centered in conversation area */\n.upload-indicator-overlay {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1rem 1.5rem;\n background: rgba(255, 255, 255, 0.95);\n border-radius: 12px;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);\n z-index: 100;\n pointer-events: none;\n}\n\n.chat-messages-container {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n background: #FFF;\n min-height: 0;\n position: relative;\n}\n\n.scroll-to-bottom-icon {\n position: sticky;\n bottom: 21px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 40px;\n margin-top: -40px;\n margin-left: auto;\n margin-right: auto;\n background: white;\n border: 1px solid #D1D5DB;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n transition: all 0.2s ease;\n z-index: 100;\n pointer-events: auto;\n}\n\n.scroll-to-bottom-icon:hover {\n background: #F3F4F6;\n border-color: #3B82F6;\n transform: translateX(-50%) translateY(-2px);\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);\n}\n\n.scroll-to-bottom-icon i {\n color: #6B7280;\n font-size: 16px;\n transition: color 0.2s;\n}\n\n.scroll-to-bottom-icon:hover i {\n color: #3B82F6;\n}\n\n.chat-input-container {\n flex-shrink: 0;\n background: #FFF;\n padding: 0 1.25rem 1.25rem 1.25rem;\n overflow: visible;\n}\n\n.loading-peripheral-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 140px;\n padding: 24px;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n border-radius: 12px;\n margin: 12px;\n animation: fadeIn 0.2s ease-in-out;\n}\n\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.modal-content {\n background: white;\n border-radius: 8px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n flex-direction: column;\n}\n\n.project-selector-modal {\n width: 600px;\n height: 500px;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid #E5E7EB;\n}\n\n.modal-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n}\n\n.modal-header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.toggle-system-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n background: #F3F4F6;\n border: 1px solid #E5E7EB;\n cursor: pointer;\n color: #6B7280;\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n transition: all 0.2s;\n}\n\n.toggle-system-btn:hover {\n background: #E5E7EB;\n border-color: #D1D5DB;\n color: #374151;\n}\n\n.toggle-system-btn.active {\n background: #3B82F6;\n border-color: #3B82F6;\n color: white;\n}\n\n.toggle-system-btn.active:hover {\n background: #2563EB;\n border-color: #2563EB;\n}\n\n.toggle-system-btn i {\n font-size: 12px;\n}\n\n.modal-close-btn {\n background: none;\n border: none;\n cursor: pointer;\n color: #6B7280;\n padding: 4px 8px;\n border-radius: 4px;\n transition: all 0.2s;\n}\n\n.modal-close-btn:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.modal-body {\n flex: 1;\n overflow: auto;\n padding: 20px;\n}\n\n.artifacts-modal {\n width: 700px;\n max-height: 600px;\n}\n\n.artifacts-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 16px;\n}\n\n.empty-state {\n grid-column: 1/-1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n}\n\n.artifact-modal-card {\n display: flex;\n flex-direction: column;\n background: white;\n border: 1.5px solid #E5E7EB;\n border-radius: 12px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.artifact-modal-card.expanded {\n border-color: #3B82F6;\n}\n\n.artifact-modal-card.system-artifact {\n opacity: 0.85;\n border-color: #D1D5DB;\n border-style: dashed;\n position: relative;\n}\n\n.artifact-modal-card.system-artifact::before {\n content: \"SYSTEM\";\n position: absolute;\n top: 8px;\n right: 8px;\n font-size: 9px;\n font-weight: 600;\n color: #9CA3AF;\n background: #F3F4F6;\n padding: 2px 6px;\n border-radius: 3px;\n letter-spacing: 0.5px;\n z-index: 10;\n}\n\n.artifact-modal-card.system-artifact:hover {\n border-color: #9CA3AF;\n box-shadow: 0 4px 12px rgba(156, 163, 175, 0.15);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n}\n\n.artifact-card-header:hover {\n background: #F9FAFB;\n}\n\n.artifact-modal-card:hover {\n border-color: #3B82F6;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);\n transform: translateY(-2px);\n}\n\n.artifact-modal-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, #EFF6FF 0%, #DBEAFE 100%);\n border-radius: 10px;\n color: #3B82F6;\n flex-shrink: 0;\n}\n\n.artifact-modal-icon i {\n font-size: 18px;\n}\n\n.artifact-modal-info {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-modal-title {\n font-size: 14px;\n font-weight: 600;\n color: #1F2937;\n margin-bottom: 4px;\n}\n\n.artifact-modal-meta {\n font-size: 12px;\n color: #6B7280;\n}\n\n.artifact-modal-action {\n color: #9CA3AF;\n transition: color 0.2s;\n}\n\n.artifact-modal-card:hover .artifact-modal-action {\n color: #3B82F6;\n}\n\n.expand-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n background: transparent;\n color: #6B7280;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.expand-btn:hover {\n background: #F3F4F6;\n color: #3B82F6;\n}\n\n.artifact-versions-list {\n display: flex;\n flex-direction: column;\n padding: 0 1rem 1rem 1rem;\n background: #F9FAFB;\n}\n\n.artifact-version-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px 12px 68px;\n cursor: pointer;\n transition: background 0.15s;\n}\n.artifact-version-item:hover {\n background: #F3F4F6;\n}\n.artifact-version-item .version-badge {\n display: inline-block;\n padding: 4px 8px;\n background: #EEF2FF;\n color: #4F46E5;\n font-size: 12px;\n font-weight: 600;\n font-family: monospace;\n border-radius: 4px;\n}\n.artifact-version-item .version-open-text {\n flex: 1;\n font-size: 13px;\n color: #6B7280;\n}\n.artifact-version-item i {\n color: #9CA3AF;\n font-size: 12px;\n}\n.artifact-version-item:hover .version-badge {\n background: #4F46E5;\n color: white;\n}\n.artifact-version-item:hover .version-open-text {\n color: #3B82F6;\n}\n.artifact-version-item:hover i {\n color: #3B82F6;\n}\n\n.loading-peripheral-content {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px 24px;\n background: white;\n border: 2px solid #E5E7EB;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);\n color: #4B5563;\n font-size: 14px;\n font-weight: 500;\n}\n.loading-peripheral-content i {\n font-size: 20px;\n color: #9333EA;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n.conversation-loading-state {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n}\n\n.loading-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding-top: 20px;\n gap: 16px;\n color: #6B7280;\n font-size: 15px;\n}\n.loading-content i {\n font-size: 32px;\n color: #3B82F6;\n}\n.loading-content span {\n font-weight: 500;\n}\n\n/* Mobile adjustments: 481px - 768px */\n@media (max-width: 768px) {\n .chat-header {\n padding: 8px 12px;\n gap: 6px;\n flex-direction: row;\n flex-wrap: wrap;\n align-items: center;\n position: relative;\n }\n .chat-info {\n flex-direction: row;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n order: 1;\n }\n .chat-title {\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 {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n display: none; /* Hide on mobile to save space */\n }\n .test-indicator {\n margin-left: 0;\n font-size: 10px;\n padding: 3px 8px;\n height: 24px;\n }\n /* Action buttons - icon only on mobile */\n .chat-actions-buttons {\n order: 2;\n flex-shrink: 0;\n }\n .chat-actions-buttons .action-btn {\n padding: 6px 8px;\n min-width: auto;\n }\n .chat-actions-buttons .action-btn .btn-label {\n display: none;\n }\n .chat-actions {\n flex-wrap: nowrap;\n }\n .chat-members,\n .artifact-indicator {\n padding: 5px 7px;\n font-size: 13px;\n }\n .action-btn {\n padding: 6px 8px;\n font-size: 12px;\n }\n .ambient-agent-indicator {\n font-size: 12px;\n padding: 4px 8px;\n }\n .project-selector-modal {\n width: min(95vw, 600px);\n height: auto;\n }\n .artifacts-modal {\n width: min(95vw, 700px);\n }\n .artifacts-grid {\n grid-template-columns: 1fr;\n }\n .chat-input-container {\n padding: 0 0.75rem 0.75rem 0.75rem;\n }\n .scroll-to-bottom-icon {\n bottom: 16px;\n width: 36px;\n height: 36px;\n }\n /* Artifact pane - full width overlay on mobile, overlapping header */\n .chat-content-area {\n position: relative;\n }\n .chat-artifact-pane {\n position: fixed;\n left: 0;\n right: 0;\n top: 56px; /* 48px nav + 8px dark strip above blue border */\n bottom: 0;\n width: 100% !important;\n z-index: 100;\n background: #FFF;\n }\n .resize-handle {\n display: none;\n }\n}\n/* Small Phone adjustments: <= 480px */\n@media (max-width: 480px) {\n .chat-header {\n padding: 6px 8px;\n gap: 4px;\n }\n .chat-title {\n font-size: 14px;\n font-weight: 700;\n }\n .project-tag {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n display: none;\n }\n .test-indicator {\n font-size: 9px;\n padding: 2px 6px;\n height: 20px;\n }\n .chat-members,\n .artifact-indicator {\n padding: 4px 8px;\n font-size: 11px;\n }\n .action-btn {\n padding: 5px 7px;\n font-size: 11px;\n }\n .ambient-agent-indicator {\n font-size: 11px;\n padding: 3px 6px;\n }\n .project-selector-modal,\n .artifacts-modal {\n width: 100vw;\n height: 100vh;\n border-radius: 0;\n }\n .chat-input-container {\n padding: 0 0.5rem 0.5rem 0.5rem;\n }\n .scroll-to-bottom-icon {\n bottom: 12px;\n width: 32px;\n height: 32px;\n }\n .scroll-to-bottom-icon i {\n font-size: 14px;\n }\n}\n"] }]
2260
+ }], () => [{ type: i1.ConversationDataService }, { type: i2.AgentStateService }, { type: i3.ConversationAgentService }, { type: i4.ActiveTasksService }, { type: i0.ChangeDetectorRef }, { type: i5.MentionAutocompleteService }, { type: i6.ArtifactPermissionService }, { type: i7.DialogService }, { type: i8.ConversationAttachmentService }, { type: i9.ConversationStreamingService }], { environmentId: [{
2063
2261
  type: Input
2064
2262
  }], currentUser: [{
2065
2263
  type: Input
@@ -2073,10 +2271,14 @@ export class ConversationChatAreaComponent {
2073
2271
  type: Input
2074
2272
  }], pendingMessage: [{
2075
2273
  type: Input
2274
+ }], pendingAttachments: [{
2275
+ type: Input
2076
2276
  }], pendingArtifactId: [{
2077
2277
  type: Input
2078
2278
  }], pendingArtifactVersionNumber: [{
2079
2279
  type: Input
2280
+ }], showSidebarToggle: [{
2281
+ type: Input
2080
2282
  }], conversationRenamed: [{
2081
2283
  type: Output
2082
2284
  }], openEntityRecord: [{
@@ -2085,6 +2287,8 @@ export class ConversationChatAreaComponent {
2085
2287
  type: Output
2086
2288
  }], artifactLinkClicked: [{
2087
2289
  type: Output
2290
+ }], sidebarToggleClicked: [{
2291
+ type: Output
2088
2292
  }], conversationCreated: [{
2089
2293
  type: Output
2090
2294
  }], threadOpened: [{
@@ -2107,5 +2311,5 @@ export class ConversationChatAreaComponent {
2107
2311
  type: ViewChild,
2108
2312
  args: [ArtifactViewerPanelComponent]
2109
2313
  }] }); })();
2110
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 23 }); })();
2314
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ConversationChatAreaComponent, { className: "ConversationChatAreaComponent", filePath: "src/lib/components/conversation/conversation-chat-area.component.ts", lineNumber: 30 }); })();
2111
2315
  //# sourceMappingURL=conversation-chat-area.component.js.map