@memberjunction/ng-conversations 2.104.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.
- package/README.md +197 -0
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts +20 -0
- package/dist/lib/components/active-tasks/active-tasks-panel.component.d.ts.map +1 -0
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js +125 -0
- package/dist/lib/components/active-tasks/active-tasks-panel.component.js.map +1 -0
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts +48 -0
- package/dist/lib/components/agent/active-agent-indicator.component.d.ts.map +1 -0
- package/dist/lib/components/agent/active-agent-indicator.component.js +199 -0
- package/dist/lib/components/agent/active-agent-indicator.component.js.map +1 -0
- package/dist/lib/components/agent/agent-process-panel.component.d.ts +30 -0
- package/dist/lib/components/agent/agent-process-panel.component.d.ts.map +1 -0
- package/dist/lib/components/agent/agent-process-panel.component.js +333 -0
- package/dist/lib/components/agent/agent-process-panel.component.js.map +1 -0
- package/dist/lib/components/artifact/artifact-panel.component.d.ts +22 -0
- package/dist/lib/components/artifact/artifact-panel.component.d.ts.map +1 -0
- package/dist/lib/components/artifact/artifact-panel.component.js +237 -0
- package/dist/lib/components/artifact/artifact-panel.component.js.map +1 -0
- package/dist/lib/components/artifact/artifact-upload-modal.component.d.ts +39 -0
- package/dist/lib/components/artifact/artifact-upload-modal.component.d.ts.map +1 -0
- package/dist/lib/components/artifact/artifact-upload-modal.component.js +384 -0
- package/dist/lib/components/artifact/artifact-upload-modal.component.js.map +1 -0
- package/dist/lib/components/artifact/artifact-version-history.component.d.ts +28 -0
- package/dist/lib/components/artifact/artifact-version-history.component.d.ts.map +1 -0
- package/dist/lib/components/artifact/artifact-version-history.component.js +280 -0
- package/dist/lib/components/artifact/artifact-version-history.component.js.map +1 -0
- package/dist/lib/components/artifact/artifact-viewer-panel.component.d.ts +22 -0
- package/dist/lib/components/artifact/artifact-viewer-panel.component.d.ts.map +1 -0
- package/dist/lib/components/artifact/artifact-viewer-panel.component.js +182 -0
- package/dist/lib/components/artifact/artifact-viewer-panel.component.js.map +1 -0
- package/dist/lib/components/artifact/artifact-viewer.component.d.ts +27 -0
- package/dist/lib/components/artifact/artifact-viewer.component.d.ts.map +1 -0
- package/dist/lib/components/artifact/artifact-viewer.component.js +266 -0
- package/dist/lib/components/artifact/artifact-viewer.component.js.map +1 -0
- package/dist/lib/components/artifact/inline-artifact.component.d.ts +46 -0
- package/dist/lib/components/artifact/inline-artifact.component.d.ts.map +1 -0
- package/dist/lib/components/artifact/inline-artifact.component.js +447 -0
- package/dist/lib/components/artifact/inline-artifact.component.js.map +1 -0
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts +18 -0
- package/dist/lib/components/collection/collection-artifact-card.component.d.ts.map +1 -0
- package/dist/lib/components/collection/collection-artifact-card.component.js +147 -0
- package/dist/lib/components/collection/collection-artifact-card.component.js.map +1 -0
- package/dist/lib/components/collection/collection-form-modal.component.d.ts +33 -0
- package/dist/lib/components/collection/collection-form-modal.component.d.ts.map +1 -0
- package/dist/lib/components/collection/collection-form-modal.component.js +245 -0
- package/dist/lib/components/collection/collection-form-modal.component.js.map +1 -0
- package/dist/lib/components/collection/collection-tree.component.d.ts +42 -0
- package/dist/lib/components/collection/collection-tree.component.d.ts.map +1 -0
- package/dist/lib/components/collection/collection-tree.component.js +482 -0
- package/dist/lib/components/collection/collection-tree.component.js.map +1 -0
- package/dist/lib/components/collection/collection-view.component.d.ts +31 -0
- package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -0
- package/dist/lib/components/collection/collection-view.component.js +254 -0
- package/dist/lib/components/collection/collection-view.component.js.map +1 -0
- package/dist/lib/components/collection/collections-full-view.component.d.ts +55 -0
- package/dist/lib/components/collection/collections-full-view.component.d.ts.map +1 -0
- package/dist/lib/components/collection/collections-full-view.component.js +578 -0
- package/dist/lib/components/collection/collections-full-view.component.js.map +1 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +160 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.js +891 -0
- package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -0
- package/dist/lib/components/conversation/conversation-list.component.d.ts +29 -0
- package/dist/lib/components/conversation/conversation-list.component.d.ts.map +1 -0
- package/dist/lib/components/conversation/conversation-list.component.js +255 -0
- package/dist/lib/components/conversation/conversation-list.component.js.map +1 -0
- package/dist/lib/components/dialogs/input-dialog.component.d.ts +17 -0
- package/dist/lib/components/dialogs/input-dialog.component.d.ts.map +1 -0
- package/dist/lib/components/dialogs/input-dialog.component.js +122 -0
- package/dist/lib/components/dialogs/input-dialog.component.js.map +1 -0
- package/dist/lib/components/export/export-modal.component.d.ts +37 -0
- package/dist/lib/components/export/export-modal.component.d.ts.map +1 -0
- package/dist/lib/components/export/export-modal.component.js +414 -0
- package/dist/lib/components/export/export-modal.component.js.map +1 -0
- package/dist/lib/components/library/library-full-view.component.d.ts +36 -0
- package/dist/lib/components/library/library-full-view.component.d.ts.map +1 -0
- package/dist/lib/components/library/library-full-view.component.js +270 -0
- package/dist/lib/components/library/library-full-view.component.js.map +1 -0
- package/dist/lib/components/members/members-modal.component.d.ts +42 -0
- package/dist/lib/components/members/members-modal.component.d.ts.map +1 -0
- package/dist/lib/components/members/members-modal.component.js +352 -0
- package/dist/lib/components/members/members-modal.component.js.map +1 -0
- package/dist/lib/components/mention/mention-dropdown.component.d.ts +44 -0
- package/dist/lib/components/mention/mention-dropdown.component.d.ts.map +1 -0
- package/dist/lib/components/mention/mention-dropdown.component.js +194 -0
- package/dist/lib/components/mention/mention-dropdown.component.js.map +1 -0
- package/dist/lib/components/message/message-input.component.d.ts +137 -0
- package/dist/lib/components/message/message-input.component.d.ts.map +1 -0
- package/dist/lib/components/message/message-input.component.js +1159 -0
- package/dist/lib/components/message/message-input.component.js.map +1 -0
- package/dist/lib/components/message/message-item.component.d.ts +140 -0
- package/dist/lib/components/message/message-item.component.d.ts.map +1 -0
- package/dist/lib/components/message/message-item.component.js +817 -0
- package/dist/lib/components/message/message-item.component.js.map +1 -0
- package/dist/lib/components/message/message-list.component.d.ts +77 -0
- package/dist/lib/components/message/message-list.component.d.ts.map +1 -0
- package/dist/lib/components/message/message-list.component.js +316 -0
- package/dist/lib/components/message/message-list.component.js.map +1 -0
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts +13 -0
- package/dist/lib/components/navigation/conversation-navigation.component.d.ts.map +1 -0
- package/dist/lib/components/navigation/conversation-navigation.component.js +88 -0
- package/dist/lib/components/navigation/conversation-navigation.component.js.map +1 -0
- package/dist/lib/components/notification/activity-indicator.component.d.ts +11 -0
- package/dist/lib/components/notification/activity-indicator.component.d.ts.map +1 -0
- package/dist/lib/components/notification/activity-indicator.component.js +56 -0
- package/dist/lib/components/notification/activity-indicator.component.js.map +1 -0
- package/dist/lib/components/notification/notification-badge.component.d.ts +27 -0
- package/dist/lib/components/notification/notification-badge.component.d.ts.map +1 -0
- package/dist/lib/components/notification/notification-badge.component.js +160 -0
- package/dist/lib/components/notification/notification-badge.component.js.map +1 -0
- package/dist/lib/components/project/project-form-modal.component.d.ts +34 -0
- package/dist/lib/components/project/project-form-modal.component.d.ts.map +1 -0
- package/dist/lib/components/project/project-form-modal.component.js +357 -0
- package/dist/lib/components/project/project-form-modal.component.js.map +1 -0
- package/dist/lib/components/project/project-selector.component.d.ts +36 -0
- package/dist/lib/components/project/project-selector.component.d.ts.map +1 -0
- package/dist/lib/components/project/project-selector.component.js +317 -0
- package/dist/lib/components/project/project-selector.component.js.map +1 -0
- package/dist/lib/components/search/search-panel.component.d.ts +120 -0
- package/dist/lib/components/search/search-panel.component.d.ts.map +1 -0
- package/dist/lib/components/search/search-panel.component.js +714 -0
- package/dist/lib/components/search/search-panel.component.js.map +1 -0
- package/dist/lib/components/share/share-modal.component.d.ts +46 -0
- package/dist/lib/components/share/share-modal.component.d.ts.map +1 -0
- package/dist/lib/components/share/share-modal.component.js +431 -0
- package/dist/lib/components/share/share-modal.component.js.map +1 -0
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts +18 -0
- package/dist/lib/components/sidebar/conversation-sidebar.component.d.ts.map +1 -0
- package/dist/lib/components/sidebar/conversation-sidebar.component.js +81 -0
- package/dist/lib/components/sidebar/conversation-sidebar.component.js.map +1 -0
- package/dist/lib/components/task/task-form-modal.component.d.ts +42 -0
- package/dist/lib/components/task/task-form-modal.component.d.ts.map +1 -0
- package/dist/lib/components/task/task-form-modal.component.js +329 -0
- package/dist/lib/components/task/task-form-modal.component.js.map +1 -0
- package/dist/lib/components/task/task-item.component.d.ts +22 -0
- package/dist/lib/components/task/task-item.component.d.ts.map +1 -0
- package/dist/lib/components/task/task-item.component.js +234 -0
- package/dist/lib/components/task/task-item.component.js.map +1 -0
- package/dist/lib/components/task/task-list.component.d.ts +32 -0
- package/dist/lib/components/task/task-list.component.d.ts.map +1 -0
- package/dist/lib/components/task/task-list.component.js +290 -0
- package/dist/lib/components/task/task-list.component.js.map +1 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts +27 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.d.ts.map +1 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.js +254 -0
- package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -0
- package/dist/lib/components/thread/thread-panel.component.d.ts +65 -0
- package/dist/lib/components/thread/thread-panel.component.d.ts.map +1 -0
- package/dist/lib/components/thread/thread-panel.component.js +325 -0
- package/dist/lib/components/thread/thread-panel.component.js.map +1 -0
- package/dist/lib/components/toast/toast.component.d.ts +26 -0
- package/dist/lib/components/toast/toast.component.d.ts.map +1 -0
- package/dist/lib/components/toast/toast.component.js +108 -0
- package/dist/lib/components/toast/toast.component.js.map +1 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts +75 -0
- package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -0
- package/dist/lib/components/workspace/conversation-workspace.component.js +299 -0
- package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -0
- package/dist/lib/conversations.module.d.ts +62 -0
- package/dist/lib/conversations.module.d.ts.map +1 -0
- package/dist/lib/conversations.module.js +248 -0
- package/dist/lib/conversations.module.js.map +1 -0
- package/dist/lib/directives/search-shortcut.directive.d.ts +17 -0
- package/dist/lib/directives/search-shortcut.directive.d.ts.map +1 -0
- package/dist/lib/directives/search-shortcut.directive.js +39 -0
- package/dist/lib/directives/search-shortcut.directive.js.map +1 -0
- package/dist/lib/models/conversation-state.model.d.ts +72 -0
- package/dist/lib/models/conversation-state.model.d.ts.map +1 -0
- package/dist/lib/models/conversation-state.model.js +2 -0
- package/dist/lib/models/conversation-state.model.js.map +1 -0
- package/dist/lib/models/notification.model.d.ts +89 -0
- package/dist/lib/models/notification.model.d.ts.map +1 -0
- package/dist/lib/models/notification.model.js +11 -0
- package/dist/lib/models/notification.model.js.map +1 -0
- package/dist/lib/services/active-tasks.service.d.ts +65 -0
- package/dist/lib/services/active-tasks.service.d.ts.map +1 -0
- package/dist/lib/services/active-tasks.service.js +95 -0
- package/dist/lib/services/active-tasks.service.js.map +1 -0
- package/dist/lib/services/agent-state.service.d.ts +78 -0
- package/dist/lib/services/agent-state.service.d.ts.map +1 -0
- package/dist/lib/services/agent-state.service.js +213 -0
- package/dist/lib/services/agent-state.service.js.map +1 -0
- package/dist/lib/services/artifact-state.service.d.ts +114 -0
- package/dist/lib/services/artifact-state.service.d.ts.map +1 -0
- package/dist/lib/services/artifact-state.service.js +288 -0
- package/dist/lib/services/artifact-state.service.js.map +1 -0
- package/dist/lib/services/conversation-agent.service.d.ts +79 -0
- package/dist/lib/services/conversation-agent.service.d.ts.map +1 -0
- package/dist/lib/services/conversation-agent.service.js +259 -0
- package/dist/lib/services/conversation-agent.service.js.map +1 -0
- package/dist/lib/services/conversation-state.service.d.ts +122 -0
- package/dist/lib/services/conversation-state.service.d.ts.map +1 -0
- package/dist/lib/services/conversation-state.service.js +255 -0
- package/dist/lib/services/conversation-state.service.js.map +1 -0
- package/dist/lib/services/dialog.service.d.ts +54 -0
- package/dist/lib/services/dialog.service.d.ts.map +1 -0
- package/dist/lib/services/dialog.service.js +157 -0
- package/dist/lib/services/dialog.service.js.map +1 -0
- package/dist/lib/services/export.service.d.ts +25 -0
- package/dist/lib/services/export.service.d.ts.map +1 -0
- package/dist/lib/services/export.service.js +237 -0
- package/dist/lib/services/export.service.js.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts +59 -0
- package/dist/lib/services/mention-autocomplete.service.d.ts.map +1 -0
- package/dist/lib/services/mention-autocomplete.service.js +160 -0
- package/dist/lib/services/mention-autocomplete.service.js.map +1 -0
- package/dist/lib/services/mention-parser.service.d.ts +46 -0
- package/dist/lib/services/mention-parser.service.d.ts.map +1 -0
- package/dist/lib/services/mention-parser.service.js +156 -0
- package/dist/lib/services/mention-parser.service.js.map +1 -0
- package/dist/lib/services/notification.service.d.ts +108 -0
- package/dist/lib/services/notification.service.d.ts.map +1 -0
- package/dist/lib/services/notification.service.js +431 -0
- package/dist/lib/services/notification.service.js.map +1 -0
- package/dist/lib/services/search.service.d.ts +144 -0
- package/dist/lib/services/search.service.d.ts.map +1 -0
- package/dist/lib/services/search.service.js +370 -0
- package/dist/lib/services/search.service.js.map +1 -0
- package/dist/lib/services/toast.service.d.ts +46 -0
- package/dist/lib/services/toast.service.d.ts.map +1 -0
- package/dist/lib/services/toast.service.js +76 -0
- package/dist/lib/services/toast.service.js.map +1 -0
- package/dist/public-api.d.ts +42 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +49 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { CompositeKey, KeyValuePair } from '@memberjunction/core';
|
|
3
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
4
|
+
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "../../services/mention-parser.service";
|
|
7
|
+
import * as i2 from "../../services/mention-autocomplete.service";
|
|
8
|
+
import * as i3 from "@angular/common";
|
|
9
|
+
import * as i4 from "@angular/forms";
|
|
10
|
+
import * as i5 from "ngx-markdown";
|
|
11
|
+
function MessageItemComponent_span_11_Template(rf, ctx) { if (rf & 1) {
|
|
12
|
+
i0.ɵɵelementStart(0, "span", 16);
|
|
13
|
+
i0.ɵɵelement(1, "i", 17);
|
|
14
|
+
i0.ɵɵtext(2);
|
|
15
|
+
i0.ɵɵelementEnd();
|
|
16
|
+
} if (rf & 2) {
|
|
17
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
18
|
+
i0.ɵɵadvance(2);
|
|
19
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r0.formattedGenerationTime, " ");
|
|
20
|
+
} }
|
|
21
|
+
function MessageItemComponent_span_12_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
23
|
+
i0.ɵɵelementStart(0, "span", 18);
|
|
24
|
+
i0.ɵɵlistener("click", function MessageItemComponent_span_12_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleAgentDetails()); });
|
|
25
|
+
i0.ɵɵelement(1, "i", 19);
|
|
26
|
+
i0.ɵɵelementEnd();
|
|
27
|
+
} if (rf & 2) {
|
|
28
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
29
|
+
i0.ɵɵclassProp("expanded", ctx_r0.isAgentDetailsExpanded);
|
|
30
|
+
} }
|
|
31
|
+
function MessageItemComponent_span_13_Template(rf, ctx) { if (rf & 1) {
|
|
32
|
+
i0.ɵɵelementStart(0, "span", 20);
|
|
33
|
+
i0.ɵɵelement(1, "i", 2);
|
|
34
|
+
i0.ɵɵelementStart(2, "span", 21);
|
|
35
|
+
i0.ɵɵtext(3);
|
|
36
|
+
i0.ɵɵelementEnd()();
|
|
37
|
+
} if (rf & 2) {
|
|
38
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
39
|
+
i0.ɵɵclassProp("error", ctx_r0.messageStatus === "Error");
|
|
40
|
+
i0.ɵɵadvance();
|
|
41
|
+
i0.ɵɵproperty("ngClass", ctx_r0.messageStatus === "Error" ? "fa-exclamation-triangle" : "fa-circle-notch fa-spin");
|
|
42
|
+
i0.ɵɵadvance(2);
|
|
43
|
+
i0.ɵɵtextInterpolate(ctx_r0.getStatusText());
|
|
44
|
+
} }
|
|
45
|
+
function MessageItemComponent_span_14_Template(rf, ctx) { if (rf & 1) {
|
|
46
|
+
i0.ɵɵelementStart(0, "span", 22);
|
|
47
|
+
i0.ɵɵtext(1);
|
|
48
|
+
i0.ɵɵelementEnd();
|
|
49
|
+
} if (rf & 2) {
|
|
50
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
51
|
+
i0.ɵɵadvance();
|
|
52
|
+
i0.ɵɵtextInterpolate(ctx_r0._elapsedTimeFormatted);
|
|
53
|
+
} }
|
|
54
|
+
function MessageItemComponent_Conditional_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
55
|
+
i0.ɵɵelementStart(0, "span", 25);
|
|
56
|
+
i0.ɵɵtext(1, "(edited)");
|
|
57
|
+
i0.ɵɵelementEnd();
|
|
58
|
+
} }
|
|
59
|
+
function MessageItemComponent_Conditional_16_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
60
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
61
|
+
i0.ɵɵelementStart(0, "div", 27);
|
|
62
|
+
i0.ɵɵlistener("click", function MessageItemComponent_Conditional_16_Conditional_3_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onArtifactClick()); });
|
|
63
|
+
i0.ɵɵelementStart(1, "div", 28)(2, "div", 29);
|
|
64
|
+
i0.ɵɵelement(3, "i", 30);
|
|
65
|
+
i0.ɵɵelementEnd();
|
|
66
|
+
i0.ɵɵelementStart(4, "div", 31)(5, "div", 32);
|
|
67
|
+
i0.ɵɵtext(6, "Generated Artifact");
|
|
68
|
+
i0.ɵɵelementEnd();
|
|
69
|
+
i0.ɵɵelementStart(7, "div", 33);
|
|
70
|
+
i0.ɵɵtext(8, "Click to view the generated content");
|
|
71
|
+
i0.ɵɵelementEnd()()()();
|
|
72
|
+
} }
|
|
73
|
+
function MessageItemComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
74
|
+
i0.ɵɵelementStart(0, "div", 23);
|
|
75
|
+
i0.ɵɵelement(1, "markdown", 24);
|
|
76
|
+
i0.ɵɵtemplate(2, MessageItemComponent_Conditional_16_Conditional_2_Template, 2, 0, "span", 25);
|
|
77
|
+
i0.ɵɵelementEnd();
|
|
78
|
+
i0.ɵɵtemplate(3, MessageItemComponent_Conditional_16_Conditional_3_Template, 9, 0, "div", 26);
|
|
79
|
+
} if (rf & 2) {
|
|
80
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
81
|
+
i0.ɵɵadvance();
|
|
82
|
+
i0.ɵɵproperty("data", ctx_r0.displayMessage);
|
|
83
|
+
i0.ɵɵadvance();
|
|
84
|
+
i0.ɵɵconditional(ctx_r0.isMessageEdited ? 2 : -1);
|
|
85
|
+
i0.ɵɵadvance();
|
|
86
|
+
i0.ɵɵconditional(ctx_r0.hasArtifact ? 3 : -1);
|
|
87
|
+
} }
|
|
88
|
+
function MessageItemComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
89
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
90
|
+
i0.ɵɵelementStart(0, "div", 12)(1, "textarea", 34);
|
|
91
|
+
i0.ɵɵtwoWayListener("ngModelChange", function MessageItemComponent_Conditional_17_Template_textarea_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.editedText, $event) || (ctx_r0.editedText = $event); return i0.ɵɵresetView($event); });
|
|
92
|
+
i0.ɵɵlistener("keydown", function MessageItemComponent_Conditional_17_Template_textarea_keydown_1_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onEditKeydown($event)); });
|
|
93
|
+
i0.ɵɵelementEnd();
|
|
94
|
+
i0.ɵɵelementStart(2, "div", 35)(3, "button", 36);
|
|
95
|
+
i0.ɵɵlistener("click", function MessageItemComponent_Conditional_17_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.saveEdit()); });
|
|
96
|
+
i0.ɵɵelement(4, "i", 37);
|
|
97
|
+
i0.ɵɵtext(5, " Save ");
|
|
98
|
+
i0.ɵɵelementEnd();
|
|
99
|
+
i0.ɵɵelementStart(6, "button", 38);
|
|
100
|
+
i0.ɵɵlistener("click", function MessageItemComponent_Conditional_17_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.cancelEditing()); });
|
|
101
|
+
i0.ɵɵelement(7, "i", 39);
|
|
102
|
+
i0.ɵɵtext(8, " Cancel ");
|
|
103
|
+
i0.ɵɵelementEnd()();
|
|
104
|
+
i0.ɵɵelementStart(9, "div", 40);
|
|
105
|
+
i0.ɵɵtext(10, " Press Enter to save, Shift+Enter for new line, Escape to cancel ");
|
|
106
|
+
i0.ɵɵelementEnd()();
|
|
107
|
+
} if (rf & 2) {
|
|
108
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
109
|
+
i0.ɵɵadvance();
|
|
110
|
+
i0.ɵɵtwoWayProperty("ngModel", ctx_r0.editedText);
|
|
111
|
+
} }
|
|
112
|
+
function MessageItemComponent_Conditional_18_Conditional_1_div_15_Template(rf, ctx) { if (rf & 1) {
|
|
113
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "span", 47);
|
|
114
|
+
i0.ɵɵtext(2, "Duration:");
|
|
115
|
+
i0.ɵɵelementEnd();
|
|
116
|
+
i0.ɵɵelementStart(3, "span", 48);
|
|
117
|
+
i0.ɵɵtext(4);
|
|
118
|
+
i0.ɵɵelementEnd()();
|
|
119
|
+
} if (rf & 2) {
|
|
120
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
121
|
+
i0.ɵɵadvance(4);
|
|
122
|
+
i0.ɵɵtextInterpolate(ctx_r0.agentRunDuration);
|
|
123
|
+
} }
|
|
124
|
+
function MessageItemComponent_Conditional_18_Conditional_1_div_16_Template(rf, ctx) { if (rf & 1) {
|
|
125
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "span", 47);
|
|
126
|
+
i0.ɵɵtext(2, "Steps:");
|
|
127
|
+
i0.ɵɵelementEnd();
|
|
128
|
+
i0.ɵɵelementStart(3, "span", 48);
|
|
129
|
+
i0.ɵɵtext(4);
|
|
130
|
+
i0.ɵɵelementEnd()();
|
|
131
|
+
} if (rf & 2) {
|
|
132
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
133
|
+
i0.ɵɵadvance(4);
|
|
134
|
+
i0.ɵɵtextInterpolate(ctx_r0.agentRunStepCount);
|
|
135
|
+
} }
|
|
136
|
+
function MessageItemComponent_Conditional_18_Conditional_1_div_17_Template(rf, ctx) { if (rf & 1) {
|
|
137
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "span", 47);
|
|
138
|
+
i0.ɵɵtext(2, "Tokens:");
|
|
139
|
+
i0.ɵɵelementEnd();
|
|
140
|
+
i0.ɵɵelementStart(3, "span", 48);
|
|
141
|
+
i0.ɵɵtext(4);
|
|
142
|
+
i0.ɵɵelementEnd()();
|
|
143
|
+
} if (rf & 2) {
|
|
144
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
145
|
+
i0.ɵɵadvance(4);
|
|
146
|
+
i0.ɵɵtextInterpolate(ctx_r0.formatNumber(ctx_r0.agentRunTotalTokens));
|
|
147
|
+
} }
|
|
148
|
+
function MessageItemComponent_Conditional_18_Conditional_1_div_18_Template(rf, ctx) { if (rf & 1) {
|
|
149
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "span", 47);
|
|
150
|
+
i0.ɵɵtext(2, "Cost:");
|
|
151
|
+
i0.ɵɵelementEnd();
|
|
152
|
+
i0.ɵɵelementStart(3, "span", 48);
|
|
153
|
+
i0.ɵɵtext(4);
|
|
154
|
+
i0.ɵɵelementEnd()();
|
|
155
|
+
} if (rf & 2) {
|
|
156
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
157
|
+
i0.ɵɵadvance(4);
|
|
158
|
+
i0.ɵɵtextInterpolate1("\\$", ctx_r0.agentRunTotalCost.toFixed(4), "");
|
|
159
|
+
} }
|
|
160
|
+
function MessageItemComponent_Conditional_18_Conditional_1_div_19_Template(rf, ctx) { if (rf & 1) {
|
|
161
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "span", 47);
|
|
162
|
+
i0.ɵɵtext(2, "Status:");
|
|
163
|
+
i0.ɵɵelementEnd();
|
|
164
|
+
i0.ɵɵelementStart(3, "span", 52);
|
|
165
|
+
i0.ɵɵtext(4);
|
|
166
|
+
i0.ɵɵelementEnd()();
|
|
167
|
+
} if (rf & 2) {
|
|
168
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
169
|
+
i0.ɵɵadvance(3);
|
|
170
|
+
i0.ɵɵclassMap("status-" + ctx_r0.agentRun.Status.toLowerCase());
|
|
171
|
+
i0.ɵɵadvance();
|
|
172
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r0.agentRun.Status, " ");
|
|
173
|
+
} }
|
|
174
|
+
function MessageItemComponent_Conditional_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
175
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
176
|
+
i0.ɵɵelementStart(0, "div", 41)(1, "div", 42);
|
|
177
|
+
i0.ɵɵelement(2, "i", 43);
|
|
178
|
+
i0.ɵɵelementStart(3, "span")(4, "a", 44);
|
|
179
|
+
i0.ɵɵlistener("click", function MessageItemComponent_Conditional_18_Conditional_1_Template_a_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openAgentRecord()); });
|
|
180
|
+
i0.ɵɵtext(5);
|
|
181
|
+
i0.ɵɵelementEnd();
|
|
182
|
+
i0.ɵɵtext(6, " Run Details ");
|
|
183
|
+
i0.ɵɵelementEnd()();
|
|
184
|
+
i0.ɵɵelementStart(7, "div", 45)(8, "div", 46)(9, "span", 47);
|
|
185
|
+
i0.ɵɵtext(10, "Run ID:");
|
|
186
|
+
i0.ɵɵelementEnd();
|
|
187
|
+
i0.ɵɵelementStart(11, "span", 48)(12, "a", 49);
|
|
188
|
+
i0.ɵɵlistener("click", function MessageItemComponent_Conditional_18_Conditional_1_Template_a_click_12_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openAgentRunRecord()); });
|
|
189
|
+
i0.ɵɵtext(13);
|
|
190
|
+
i0.ɵɵelement(14, "i", 50);
|
|
191
|
+
i0.ɵɵelementEnd()()();
|
|
192
|
+
i0.ɵɵtemplate(15, MessageItemComponent_Conditional_18_Conditional_1_div_15_Template, 5, 1, "div", 51)(16, MessageItemComponent_Conditional_18_Conditional_1_div_16_Template, 5, 1, "div", 51)(17, MessageItemComponent_Conditional_18_Conditional_1_div_17_Template, 5, 1, "div", 51)(18, MessageItemComponent_Conditional_18_Conditional_1_div_18_Template, 5, 1, "div", 51)(19, MessageItemComponent_Conditional_18_Conditional_1_div_19_Template, 5, 3, "div", 51);
|
|
193
|
+
i0.ɵɵelementEnd()();
|
|
194
|
+
} if (rf & 2) {
|
|
195
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
196
|
+
i0.ɵɵadvance(5);
|
|
197
|
+
i0.ɵɵtextInterpolate1(" ", (ctx_r0.aiAgentInfo == null ? null : ctx_r0.aiAgentInfo.name) || "Agent", " ");
|
|
198
|
+
i0.ɵɵadvance(8);
|
|
199
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r0.agentRun.ID, " ");
|
|
200
|
+
i0.ɵɵadvance(2);
|
|
201
|
+
i0.ɵɵproperty("ngIf", ctx_r0.agentRunDuration);
|
|
202
|
+
i0.ɵɵadvance();
|
|
203
|
+
i0.ɵɵproperty("ngIf", ctx_r0.agentRunStepCount > 0);
|
|
204
|
+
i0.ɵɵadvance();
|
|
205
|
+
i0.ɵɵproperty("ngIf", ctx_r0.agentRunTotalTokens > 0);
|
|
206
|
+
i0.ɵɵadvance();
|
|
207
|
+
i0.ɵɵproperty("ngIf", ctx_r0.agentRunTotalCost > 0);
|
|
208
|
+
i0.ɵɵadvance();
|
|
209
|
+
i0.ɵɵproperty("ngIf", ctx_r0.agentRun.Status);
|
|
210
|
+
} }
|
|
211
|
+
function MessageItemComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
212
|
+
i0.ɵɵelementStart(0, "div", 13);
|
|
213
|
+
i0.ɵɵtemplate(1, MessageItemComponent_Conditional_18_Conditional_1_Template, 20, 7, "div", 41);
|
|
214
|
+
i0.ɵɵelementEnd();
|
|
215
|
+
} if (rf & 2) {
|
|
216
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
217
|
+
i0.ɵɵadvance();
|
|
218
|
+
i0.ɵɵconditional(ctx_r0.agentRun ? 1 : -1);
|
|
219
|
+
} }
|
|
220
|
+
function MessageItemComponent_div_19_button_1_Template(rf, ctx) { if (rf & 1) {
|
|
221
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
222
|
+
i0.ɵɵelementStart(0, "button", 59);
|
|
223
|
+
i0.ɵɵlistener("click", function MessageItemComponent_div_19_button_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onRetryClick()); });
|
|
224
|
+
i0.ɵɵelement(1, "i", 60);
|
|
225
|
+
i0.ɵɵtext(2, " Retry ");
|
|
226
|
+
i0.ɵɵelementEnd();
|
|
227
|
+
} }
|
|
228
|
+
function MessageItemComponent_div_19_button_4_Template(rf, ctx) { if (rf & 1) {
|
|
229
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
230
|
+
i0.ɵɵelementStart(0, "button", 61);
|
|
231
|
+
i0.ɵɵlistener("click", function MessageItemComponent_div_19_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onEditClick()); });
|
|
232
|
+
i0.ɵɵelement(1, "i", 62);
|
|
233
|
+
i0.ɵɵelementEnd();
|
|
234
|
+
} }
|
|
235
|
+
function MessageItemComponent_div_19_Template(rf, ctx) { if (rf & 1) {
|
|
236
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
237
|
+
i0.ɵɵelementStart(0, "div", 53);
|
|
238
|
+
i0.ɵɵtemplate(1, MessageItemComponent_div_19_button_1_Template, 3, 0, "button", 54);
|
|
239
|
+
i0.ɵɵelementStart(2, "button", 55);
|
|
240
|
+
i0.ɵɵlistener("click", function MessageItemComponent_div_19_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onPinClick()); });
|
|
241
|
+
i0.ɵɵelement(3, "i", 2);
|
|
242
|
+
i0.ɵɵelementEnd();
|
|
243
|
+
i0.ɵɵtemplate(4, MessageItemComponent_div_19_button_4_Template, 2, 0, "button", 56);
|
|
244
|
+
i0.ɵɵelementStart(5, "button", 57);
|
|
245
|
+
i0.ɵɵlistener("click", function MessageItemComponent_div_19_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onDeleteClick()); });
|
|
246
|
+
i0.ɵɵelement(6, "i", 58);
|
|
247
|
+
i0.ɵɵelementEnd()();
|
|
248
|
+
} if (rf & 2) {
|
|
249
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
250
|
+
i0.ɵɵadvance();
|
|
251
|
+
i0.ɵɵproperty("ngIf", ctx_r0.messageStatus === "Error" && ctx_r0.isAIMessage);
|
|
252
|
+
i0.ɵɵadvance();
|
|
253
|
+
i0.ɵɵproperty("title", ctx_r0.message.IsPinned ? "Unpin" : "Pin");
|
|
254
|
+
i0.ɵɵadvance();
|
|
255
|
+
i0.ɵɵproperty("ngClass", ctx_r0.message.IsPinned ? "fa-thumbtack" : "fa-thumbtack");
|
|
256
|
+
i0.ɵɵadvance();
|
|
257
|
+
i0.ɵɵproperty("ngIf", ctx_r0.isUserMessage);
|
|
258
|
+
} }
|
|
259
|
+
function MessageItemComponent_div_20_Template(rf, ctx) { if (rf & 1) {
|
|
260
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
261
|
+
i0.ɵɵelementStart(0, "div", 63)(1, "button", 64);
|
|
262
|
+
i0.ɵɵlistener("click", function MessageItemComponent_div_20_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleReaction("like")); });
|
|
263
|
+
i0.ɵɵelement(2, "i", 65);
|
|
264
|
+
i0.ɵɵelementStart(3, "span", 66);
|
|
265
|
+
i0.ɵɵtext(4, "0");
|
|
266
|
+
i0.ɵɵelementEnd()();
|
|
267
|
+
i0.ɵɵelementStart(5, "button", 64);
|
|
268
|
+
i0.ɵɵlistener("click", function MessageItemComponent_div_20_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleReaction("comment")); });
|
|
269
|
+
i0.ɵɵelement(6, "i", 67);
|
|
270
|
+
i0.ɵɵelementStart(7, "span", 66);
|
|
271
|
+
i0.ɵɵtext(8, "0");
|
|
272
|
+
i0.ɵɵelementEnd()()();
|
|
273
|
+
} }
|
|
274
|
+
/**
|
|
275
|
+
* Component for displaying a single message in a conversation
|
|
276
|
+
* Follows the dynamic rendering pattern from skip-chat for optimal performance
|
|
277
|
+
* This component is created dynamically via ViewContainerRef.createComponent()
|
|
278
|
+
*/
|
|
279
|
+
export class MessageItemComponent extends BaseAngularComponent {
|
|
280
|
+
cdRef;
|
|
281
|
+
mentionParser;
|
|
282
|
+
mentionAutocomplete;
|
|
283
|
+
message;
|
|
284
|
+
conversation;
|
|
285
|
+
currentUser;
|
|
286
|
+
allMessages;
|
|
287
|
+
isProcessing = false;
|
|
288
|
+
artifactId;
|
|
289
|
+
artifactVersionId;
|
|
290
|
+
agentRun = null; // Passed from parent, loaded once per conversation
|
|
291
|
+
pinClicked = new EventEmitter();
|
|
292
|
+
editClicked = new EventEmitter();
|
|
293
|
+
deleteClicked = new EventEmitter();
|
|
294
|
+
retryClicked = new EventEmitter();
|
|
295
|
+
artifactClicked = new EventEmitter();
|
|
296
|
+
artifactActionPerformed = new EventEmitter();
|
|
297
|
+
messageEdited = new EventEmitter();
|
|
298
|
+
openEntityRecord = new EventEmitter();
|
|
299
|
+
_loadTime = Date.now();
|
|
300
|
+
_elapsedTimeInterval = null;
|
|
301
|
+
_elapsedTimeFormatted = '(0:00)';
|
|
302
|
+
isEditing = false;
|
|
303
|
+
editedText = '';
|
|
304
|
+
originalText = '';
|
|
305
|
+
// Agent run details
|
|
306
|
+
isAgentDetailsExpanded = false;
|
|
307
|
+
constructor(cdRef, mentionParser, mentionAutocomplete) {
|
|
308
|
+
super();
|
|
309
|
+
this.cdRef = cdRef;
|
|
310
|
+
this.mentionParser = mentionParser;
|
|
311
|
+
this.mentionAutocomplete = mentionAutocomplete;
|
|
312
|
+
}
|
|
313
|
+
async ngOnInit() {
|
|
314
|
+
// No longer need to load artifacts per message - they are preloaded in chat area
|
|
315
|
+
}
|
|
316
|
+
ngAfterViewInit() {
|
|
317
|
+
this._loadTime = Date.now();
|
|
318
|
+
this.startElapsedTimeUpdater();
|
|
319
|
+
this.cdRef.detectChanges();
|
|
320
|
+
}
|
|
321
|
+
ngOnDestroy() {
|
|
322
|
+
if (this._elapsedTimeInterval !== null) {
|
|
323
|
+
clearInterval(this._elapsedTimeInterval);
|
|
324
|
+
this._elapsedTimeInterval = null;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Starts the elapsed time updater interval for temporary messages
|
|
329
|
+
*/
|
|
330
|
+
startElapsedTimeUpdater() {
|
|
331
|
+
if (this.isTemporaryMessage) {
|
|
332
|
+
Promise.resolve().then(() => {
|
|
333
|
+
this._elapsedTimeFormatted = this.formatElapsedTime(this.elapsedTimeSinceLoad);
|
|
334
|
+
this.cdRef.detectChanges();
|
|
335
|
+
});
|
|
336
|
+
if (this._elapsedTimeInterval === null) {
|
|
337
|
+
this._elapsedTimeInterval = setInterval(() => {
|
|
338
|
+
this._elapsedTimeFormatted = this.formatElapsedTime(this.elapsedTimeSinceLoad);
|
|
339
|
+
Promise.resolve().then(() => {
|
|
340
|
+
this.cdRef.detectChanges();
|
|
341
|
+
});
|
|
342
|
+
}, 1000);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
formatElapsedTime(elapsedTime) {
|
|
347
|
+
let seconds = Math.floor(elapsedTime / 1000);
|
|
348
|
+
let minutes = Math.floor(seconds / 60);
|
|
349
|
+
seconds = seconds % 60;
|
|
350
|
+
let hours = Math.floor(minutes / 60);
|
|
351
|
+
minutes = minutes % 60;
|
|
352
|
+
let formattedTime = (hours > 0 ? hours + ':' : '') +
|
|
353
|
+
(minutes < 10 && hours > 0 ? '0' : '') + minutes + ':' +
|
|
354
|
+
(seconds < 10 ? '0' : '') + seconds;
|
|
355
|
+
return `(${formattedTime})`;
|
|
356
|
+
}
|
|
357
|
+
get elapsedTimeSinceLoad() {
|
|
358
|
+
return Date.now() - this._loadTime;
|
|
359
|
+
}
|
|
360
|
+
get isAIMessage() {
|
|
361
|
+
return this.message.Role?.trim().toLowerCase() === 'ai';
|
|
362
|
+
}
|
|
363
|
+
get aiAgentInfo() {
|
|
364
|
+
if (!this.isAIMessage)
|
|
365
|
+
return null;
|
|
366
|
+
// Get agent ID from denormalized field (populated when message is created)
|
|
367
|
+
const agentID = this.message.AgentID;
|
|
368
|
+
// Look up agent from AIEngineBase cache
|
|
369
|
+
if (agentID && AIEngineBase.Instance?.Agents) {
|
|
370
|
+
const agent = AIEngineBase.Instance.Agents.find(a => a.ID === agentID);
|
|
371
|
+
if (agent) {
|
|
372
|
+
return {
|
|
373
|
+
name: agent.Name || 'AI Assistant',
|
|
374
|
+
iconClass: agent.IconClass || 'fa-robot',
|
|
375
|
+
role: agent.Description || 'AI Assistant'
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
// Only log if the message is complete (should have AgentID by then)
|
|
380
|
+
if (this.message.Status === 'Complete') {
|
|
381
|
+
console.warn('⚠️ Agent not found in cache for ID:', agentID);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Note: In-progress messages won't have AgentID yet, so we don't log warnings for them
|
|
386
|
+
// Default fallback for AI messages without agent info
|
|
387
|
+
return {
|
|
388
|
+
name: 'AI Assistant',
|
|
389
|
+
iconClass: 'fa-robot',
|
|
390
|
+
role: 'AI Assistant'
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
get isUserMessage() {
|
|
394
|
+
return this.message.Role?.trim().toLowerCase() === 'user';
|
|
395
|
+
}
|
|
396
|
+
get isConversationManager() {
|
|
397
|
+
return this.aiAgentInfo?.name === 'Conversation Manager Agent' || this.aiAgentInfo?.name === 'Conversation Manager';
|
|
398
|
+
}
|
|
399
|
+
get displayMessage() {
|
|
400
|
+
let text = this.message.Message || '';
|
|
401
|
+
// For Conversation Manager, only show the delegation line (starts with emoji)
|
|
402
|
+
if (this.isConversationManager && text) {
|
|
403
|
+
const delegationMatch = text.match(/🤖.*Delegating to.*Agent.*/);
|
|
404
|
+
if (delegationMatch) {
|
|
405
|
+
text = delegationMatch[0];
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// Transform @mentions to HTML pills
|
|
409
|
+
return this.transformMentionsToHTML(text);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Transform @mentions in text to HTML badge elements
|
|
413
|
+
* Uses inline HTML that markdown will preserve
|
|
414
|
+
*/
|
|
415
|
+
transformMentionsToHTML(text) {
|
|
416
|
+
if (!text)
|
|
417
|
+
return '';
|
|
418
|
+
const agents = this.mentionAutocomplete.getAvailableAgents();
|
|
419
|
+
const users = this.mentionAutocomplete.getAvailableUsers();
|
|
420
|
+
// Parse mentions from the text
|
|
421
|
+
const parseResult = this.mentionParser.parseMentions(text, agents, users);
|
|
422
|
+
// Replace each mention with an HTML badge
|
|
423
|
+
// Note: Handle both @"Agent Name" (quoted) and @AgentName formats
|
|
424
|
+
let transformedText = text;
|
|
425
|
+
for (const mention of parseResult.mentions) {
|
|
426
|
+
const badgeClass = mention.type === 'agent' ? 'mention-badge agent' : 'mention-badge user';
|
|
427
|
+
// Match both quoted and unquoted versions
|
|
428
|
+
const quotedPattern = new RegExp(`@"${this.escapeRegex(mention.name)}"`, 'gi');
|
|
429
|
+
const unquotedPattern = new RegExp(`@${this.escapeRegex(mention.name)}(?![\\w"])`, 'gi');
|
|
430
|
+
const badgeHTML = `<span class="${badgeClass}">@${mention.name}</span>`;
|
|
431
|
+
// Replace quoted version first, then unquoted
|
|
432
|
+
transformedText = transformedText.replace(quotedPattern, badgeHTML);
|
|
433
|
+
transformedText = transformedText.replace(unquotedPattern, badgeHTML);
|
|
434
|
+
}
|
|
435
|
+
return transformedText;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Escape special regex characters
|
|
439
|
+
*/
|
|
440
|
+
escapeRegex(text) {
|
|
441
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
442
|
+
}
|
|
443
|
+
get isTemporaryMessage() {
|
|
444
|
+
return this.isAIMessage && (!this.message.ID || this.message.ID.length === 0);
|
|
445
|
+
}
|
|
446
|
+
get messageStatus() {
|
|
447
|
+
return this.message.Status || 'Complete';
|
|
448
|
+
}
|
|
449
|
+
getStatusText() {
|
|
450
|
+
switch (this.messageStatus) {
|
|
451
|
+
case 'In-Progress':
|
|
452
|
+
return 'Processing...';
|
|
453
|
+
case 'Error':
|
|
454
|
+
return 'Failed';
|
|
455
|
+
default:
|
|
456
|
+
return '';
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
get isFirstMessageInConversation() {
|
|
460
|
+
return this.allMessages.indexOf(this.message) === 0;
|
|
461
|
+
}
|
|
462
|
+
get isLastMessageInConversation() {
|
|
463
|
+
return this.allMessages.indexOf(this.message) === this.allMessages.length - 1;
|
|
464
|
+
}
|
|
465
|
+
get hasArtifact() {
|
|
466
|
+
return !!this.artifactVersionId;
|
|
467
|
+
}
|
|
468
|
+
get formattedGenerationTime() {
|
|
469
|
+
// Only show generation time for AI messages
|
|
470
|
+
if (this.isUserMessage || !this.message.__mj_CreatedAt || !this.message.__mj_UpdatedAt) {
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
// Calculate generation time from created -> updated timestamps
|
|
474
|
+
const createdAt = new Date(this.message.__mj_CreatedAt);
|
|
475
|
+
const updatedAt = new Date(this.message.__mj_UpdatedAt);
|
|
476
|
+
const diffMs = updatedAt.getTime() - createdAt.getTime();
|
|
477
|
+
// If no time difference, don't show (e.g., not yet completed)
|
|
478
|
+
if (diffMs <= 0) {
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
481
|
+
const seconds = diffMs / 1000;
|
|
482
|
+
if (seconds < 1) {
|
|
483
|
+
return `${Math.round(diffMs)}ms`;
|
|
484
|
+
}
|
|
485
|
+
else if (seconds < 60) {
|
|
486
|
+
return `${seconds.toFixed(1)}s`;
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
const mins = Math.floor(seconds / 60);
|
|
490
|
+
const secs = Math.floor(seconds % 60);
|
|
491
|
+
return `${mins}m ${secs}s`;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
get messageClasses() {
|
|
495
|
+
const classes = ['message-item'];
|
|
496
|
+
if (this.isAIMessage) {
|
|
497
|
+
classes.push('ai-message');
|
|
498
|
+
// Show in-progress styling for AI messages that are still processing
|
|
499
|
+
if (this.isTemporaryMessage || this.messageStatus === 'In-Progress') {
|
|
500
|
+
classes.push('in-progress');
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
else if (this.isUserMessage) {
|
|
504
|
+
classes.push('user-message');
|
|
505
|
+
}
|
|
506
|
+
if (this.message.IsPinned) {
|
|
507
|
+
classes.push('pinned');
|
|
508
|
+
}
|
|
509
|
+
if (this.isEditing) {
|
|
510
|
+
classes.push('editing');
|
|
511
|
+
}
|
|
512
|
+
return classes.join(' ');
|
|
513
|
+
}
|
|
514
|
+
get isMessageEdited() {
|
|
515
|
+
// Only show edited badge if user actually edited the message content
|
|
516
|
+
// Status updates don't count as edits - we need a more reliable indicator
|
|
517
|
+
// For now, we'll check if there's a significant time difference (more than 30 seconds)
|
|
518
|
+
// AND it's a user message (since AI messages get status updates frequently)
|
|
519
|
+
if (!this.message.__mj_CreatedAt || !this.message.__mj_UpdatedAt || !this.isUserMessage) {
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
// Allow 30 second threshold to avoid false positives from status updates
|
|
523
|
+
// Real edits will typically happen much later than creation
|
|
524
|
+
return this.message.__mj_UpdatedAt.getTime() - this.message.__mj_CreatedAt.getTime() > 30000;
|
|
525
|
+
}
|
|
526
|
+
onPinClick() {
|
|
527
|
+
if (!this.isProcessing) {
|
|
528
|
+
this.pinClicked.emit(this.message);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
onEditClick() {
|
|
532
|
+
if (!this.isProcessing && !this.isEditing) {
|
|
533
|
+
this.startEditing();
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
startEditing() {
|
|
537
|
+
this.originalText = this.message.Message || '';
|
|
538
|
+
this.editedText = this.originalText;
|
|
539
|
+
this.isEditing = true;
|
|
540
|
+
// Focus textarea after Angular renders it
|
|
541
|
+
Promise.resolve().then(() => {
|
|
542
|
+
const textarea = document.querySelector('.message-edit-textarea');
|
|
543
|
+
if (textarea) {
|
|
544
|
+
textarea.focus();
|
|
545
|
+
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
|
546
|
+
}
|
|
547
|
+
this.cdRef.detectChanges();
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
cancelEditing() {
|
|
551
|
+
this.isEditing = false;
|
|
552
|
+
this.editedText = '';
|
|
553
|
+
this.originalText = '';
|
|
554
|
+
this.cdRef.detectChanges();
|
|
555
|
+
}
|
|
556
|
+
async saveEdit() {
|
|
557
|
+
if (!this.editedText.trim() || this.editedText === this.originalText) {
|
|
558
|
+
this.cancelEditing();
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
try {
|
|
562
|
+
// Update the message entity
|
|
563
|
+
this.message.Message = this.editedText;
|
|
564
|
+
const saveResult = await this.message.Save();
|
|
565
|
+
if (saveResult) {
|
|
566
|
+
this.isEditing = false;
|
|
567
|
+
this.editedText = '';
|
|
568
|
+
this.originalText = '';
|
|
569
|
+
this.messageEdited.emit(this.message);
|
|
570
|
+
this.cdRef.detectChanges();
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
console.error('Failed to save message edit');
|
|
574
|
+
alert('Failed to save message. Please try again.');
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
catch (error) {
|
|
578
|
+
console.error('Error saving message edit:', error);
|
|
579
|
+
alert('Error saving message. Please try again.');
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
onEditKeydown(event) {
|
|
583
|
+
if (event.key === 'Escape') {
|
|
584
|
+
event.preventDefault();
|
|
585
|
+
this.cancelEditing();
|
|
586
|
+
}
|
|
587
|
+
else if (event.key === 'Enter' && !event.shiftKey) {
|
|
588
|
+
event.preventDefault();
|
|
589
|
+
this.saveEdit();
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
onDeleteClick() {
|
|
593
|
+
if (!this.isProcessing) {
|
|
594
|
+
this.deleteClicked.emit(this.message);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
onRetryClick() {
|
|
598
|
+
if (!this.isProcessing && this.messageStatus === 'Error') {
|
|
599
|
+
this.retryClicked.emit(this.message);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
onArtifactClick() {
|
|
603
|
+
if (this.hasArtifact && this.artifactId) {
|
|
604
|
+
this.artifactClicked.emit({
|
|
605
|
+
artifactId: this.artifactId,
|
|
606
|
+
versionId: this.artifactVersionId
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
toggleReaction(type) {
|
|
611
|
+
// TODO: Implement reaction toggling
|
|
612
|
+
console.log('Toggle reaction:', type, 'for message:', this.message.ID);
|
|
613
|
+
}
|
|
614
|
+
onSaveArtifact(event) {
|
|
615
|
+
event.stopPropagation();
|
|
616
|
+
// TODO: Implement artifact save
|
|
617
|
+
console.log('Save artifact for message:', this.message.ID);
|
|
618
|
+
}
|
|
619
|
+
onShareArtifact(event) {
|
|
620
|
+
event.stopPropagation();
|
|
621
|
+
// TODO: Implement artifact share
|
|
622
|
+
console.log('Share artifact for message:', this.message.ID);
|
|
623
|
+
}
|
|
624
|
+
onExportArtifact(event) {
|
|
625
|
+
event.stopPropagation();
|
|
626
|
+
// TODO: Implement artifact export
|
|
627
|
+
console.log('Export artifact for message:', this.message.ID);
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Whether this message has an associated agent run
|
|
631
|
+
* Based on whether the message has an AgentID (not whether agentRun object is loaded)
|
|
632
|
+
*/
|
|
633
|
+
get hasAgentRun() {
|
|
634
|
+
return !!this.message?.AgentID;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Toggle the agent details panel expansion
|
|
638
|
+
*/
|
|
639
|
+
toggleAgentDetails() {
|
|
640
|
+
this.isAgentDetailsExpanded = !this.isAgentDetailsExpanded;
|
|
641
|
+
this.cdRef.detectChanges();
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Get formatted duration for the agent run
|
|
645
|
+
* Calculate from created to updated timestamp
|
|
646
|
+
*/
|
|
647
|
+
get agentRunDuration() {
|
|
648
|
+
if (!this.agentRun || !this.agentRun.__mj_CreatedAt || !this.agentRun.__mj_UpdatedAt) {
|
|
649
|
+
return null;
|
|
650
|
+
}
|
|
651
|
+
const createdAt = new Date(this.agentRun.__mj_CreatedAt);
|
|
652
|
+
const updatedAt = new Date(this.agentRun.__mj_UpdatedAt);
|
|
653
|
+
const diffMs = updatedAt.getTime() - createdAt.getTime();
|
|
654
|
+
if (diffMs <= 0) {
|
|
655
|
+
return null;
|
|
656
|
+
}
|
|
657
|
+
const seconds = diffMs / 1000;
|
|
658
|
+
if (seconds < 1) {
|
|
659
|
+
return `${Math.round(diffMs)}ms`;
|
|
660
|
+
}
|
|
661
|
+
else if (seconds < 60) {
|
|
662
|
+
return `${seconds.toFixed(1)}s`;
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
const mins = Math.floor(seconds / 60);
|
|
666
|
+
const secs = Math.floor(seconds % 60);
|
|
667
|
+
return `${mins}m ${secs}s`;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Get total tokens used in the agent run
|
|
672
|
+
*/
|
|
673
|
+
get agentRunTotalTokens() {
|
|
674
|
+
if (!this.agentRun) {
|
|
675
|
+
return 0;
|
|
676
|
+
}
|
|
677
|
+
return (this.agentRun.TotalPromptTokensUsed || 0) + (this.agentRun.TotalCompletionTokensUsed || 0);
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Get total cost of the agent run
|
|
681
|
+
*/
|
|
682
|
+
get agentRunTotalCost() {
|
|
683
|
+
return this.agentRun?.TotalCost || 0;
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Get number of steps in the agent run
|
|
687
|
+
*/
|
|
688
|
+
get agentRunStepCount() {
|
|
689
|
+
// Count from the Steps array if available
|
|
690
|
+
if (this.agentRun && this.agentRun.Steps) {
|
|
691
|
+
return this.agentRun.Steps.length;
|
|
692
|
+
}
|
|
693
|
+
return 0;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Format number with commas
|
|
697
|
+
*/
|
|
698
|
+
formatNumber(num) {
|
|
699
|
+
return num.toLocaleString();
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Open the agent run entity record in a new tab
|
|
703
|
+
*/
|
|
704
|
+
openAgentRunRecord() {
|
|
705
|
+
if (!this.agentRun?.ID)
|
|
706
|
+
return;
|
|
707
|
+
const compositeKey = new CompositeKey([
|
|
708
|
+
new KeyValuePair('ID', this.agentRun.ID)
|
|
709
|
+
]);
|
|
710
|
+
this.openEntityRecord.emit({
|
|
711
|
+
entityName: 'MJ: AI Agent Runs',
|
|
712
|
+
compositeKey
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Open the agent entity record in a new tab
|
|
717
|
+
*/
|
|
718
|
+
openAgentRecord() {
|
|
719
|
+
if (!this.agentRun?.AgentID)
|
|
720
|
+
return;
|
|
721
|
+
const compositeKey = new CompositeKey([
|
|
722
|
+
new KeyValuePair('ID', this.agentRun.AgentID)
|
|
723
|
+
]);
|
|
724
|
+
this.openEntityRecord.emit({
|
|
725
|
+
entityName: 'AI Agents',
|
|
726
|
+
compositeKey
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
static ɵfac = function MessageItemComponent_Factory(t) { return new (t || MessageItemComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i1.MentionParserService), i0.ɵɵdirectiveInject(i2.MentionAutocompleteService)); };
|
|
730
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MessageItemComponent, selectors: [["mj-conversation-message-item"]], inputs: { message: "message", conversation: "conversation", currentUser: "currentUser", allMessages: "allMessages", isProcessing: "isProcessing", artifactId: "artifactId", artifactVersionId: "artifactVersionId", agentRun: "agentRun" }, outputs: { pinClicked: "pinClicked", editClicked: "editClicked", deleteClicked: "deleteClicked", retryClicked: "retryClicked", artifactClicked: "artifactClicked", artifactActionPerformed: "artifactActionPerformed", messageEdited: "messageEdited", openEntityRecord: "openEntityRecord" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 21, vars: 22, consts: [[1, "message-avatar"], [1, "avatar-circle"], [1, "fas", 3, "ngClass"], [1, "message-content"], [1, "message-header"], [1, "message-sender", 3, "title"], [1, "message-time"], ["class", "generation-time", 4, "ngIf"], ["class", "agent-run-icon", "title", "Click to view agent execution details", 3, "expanded", "click", 4, "ngIf"], ["class", "message-status", 3, "error", 4, "ngIf"], ["class", "message-elapsed", 4, "ngIf"], [1, "message-body"], [1, "message-edit-container"], [1, "agent-details-panel"], ["class", "message-actions", 4, "ngIf"], ["class", "message-reactions", 4, "ngIf"], [1, "generation-time"], [1, "fas", "fa-clock"], ["title", "Click to view agent execution details", 1, "agent-run-icon", 3, "click"], [1, "fas", "fa-cog"], [1, "message-status"], [1, "status-text"], [1, "message-elapsed"], [1, "message-text"], [3, "data"], [1, "edited-badge"], [1, "artifact-card"], [1, "artifact-card", 3, "click"], [1, "artifact-card-header"], [1, "artifact-card-icon"], [1, "fas", "fa-file-code"], [1, "artifact-card-content"], [1, "artifact-card-label"], [1, "artifact-card-description"], ["rows", "4", "placeholder", "Edit your message...", 1, "message-edit-textarea", 3, "ngModelChange", "keydown", "ngModel"], [1, "edit-actions"], [1, "edit-action-btn", "save", 3, "click"], [1, "fas", "fa-check"], [1, "edit-action-btn", "cancel", 3, "click"], [1, "fas", "fa-times"], [1, "edit-hint"], [1, "agent-details-content"], [1, "agent-details-header"], [1, "fas", "fa-chart-line"], ["title", "Open agent details", 1, "agent-name-link", 3, "click"], [1, "agent-details-grid"], [1, "detail-row"], [1, "detail-label"], [1, "detail-value"], ["title", "Open agent run details", 1, "run-id-link", 3, "click"], [1, "fas", "fa-external-link-alt"], ["class", "detail-row", 4, "ngIf"], [1, "detail-value", "status-badge"], [1, "message-actions"], ["class", "message-action-btn retry-btn", "title", "Retry", 3, "click", 4, "ngIf"], [1, "message-action-btn", 3, "click", "title"], ["class", "message-action-btn", "title", "Edit", 3, "click", 4, "ngIf"], ["title", "Delete", 1, "message-action-btn", "danger", 3, "click"], [1, "fas", "fa-trash"], ["title", "Retry", 1, "message-action-btn", "retry-btn", 3, "click"], [1, "fas", "fa-redo"], ["title", "Edit", 1, "message-action-btn", 3, "click"], [1, "fas", "fa-edit"], [1, "message-reactions"], [1, "reaction-btn", 3, "click"], [1, "far", "fa-thumbs-up"], [1, "reaction-count"], [1, "far", "fa-comment"]], template: function MessageItemComponent_Template(rf, ctx) { if (rf & 1) {
|
|
731
|
+
i0.ɵɵelementStart(0, "div")(1, "div", 0)(2, "div", 1);
|
|
732
|
+
i0.ɵɵelement(3, "i", 2);
|
|
733
|
+
i0.ɵɵelementEnd()();
|
|
734
|
+
i0.ɵɵelementStart(4, "div", 3)(5, "div", 4)(6, "span", 5);
|
|
735
|
+
i0.ɵɵtext(7);
|
|
736
|
+
i0.ɵɵelementEnd();
|
|
737
|
+
i0.ɵɵelementStart(8, "span", 6);
|
|
738
|
+
i0.ɵɵtext(9);
|
|
739
|
+
i0.ɵɵpipe(10, "date");
|
|
740
|
+
i0.ɵɵelementEnd();
|
|
741
|
+
i0.ɵɵtemplate(11, MessageItemComponent_span_11_Template, 3, 1, "span", 7)(12, MessageItemComponent_span_12_Template, 2, 2, "span", 8)(13, MessageItemComponent_span_13_Template, 4, 4, "span", 9)(14, MessageItemComponent_span_14_Template, 2, 1, "span", 10);
|
|
742
|
+
i0.ɵɵelementEnd();
|
|
743
|
+
i0.ɵɵelementStart(15, "div", 11);
|
|
744
|
+
i0.ɵɵtemplate(16, MessageItemComponent_Conditional_16_Template, 4, 3)(17, MessageItemComponent_Conditional_17_Template, 11, 1, "div", 12)(18, MessageItemComponent_Conditional_18_Template, 2, 1, "div", 13);
|
|
745
|
+
i0.ɵɵelementEnd();
|
|
746
|
+
i0.ɵɵtemplate(19, MessageItemComponent_div_19_Template, 7, 4, "div", 14)(20, MessageItemComponent_div_20_Template, 9, 0, "div", 15);
|
|
747
|
+
i0.ɵɵelementEnd()();
|
|
748
|
+
} if (rf & 2) {
|
|
749
|
+
i0.ɵɵclassMap(ctx.messageClasses);
|
|
750
|
+
i0.ɵɵadvance(2);
|
|
751
|
+
i0.ɵɵclassProp("ai-avatar", ctx.isAIMessage)("user-avatar", ctx.isUserMessage);
|
|
752
|
+
i0.ɵɵadvance();
|
|
753
|
+
i0.ɵɵproperty("ngClass", ctx.isAIMessage ? (ctx.aiAgentInfo == null ? null : ctx.aiAgentInfo.iconClass) || "fa-robot" : "fa-user");
|
|
754
|
+
i0.ɵɵadvance(3);
|
|
755
|
+
i0.ɵɵproperty("title", ctx.isAIMessage ? (ctx.aiAgentInfo == null ? null : ctx.aiAgentInfo.role) || "AI Assistant" : "");
|
|
756
|
+
i0.ɵɵadvance();
|
|
757
|
+
i0.ɵɵtextInterpolate1(" ", ctx.isAIMessage ? (ctx.aiAgentInfo == null ? null : ctx.aiAgentInfo.name) || "AI Assistant" : ctx.currentUser.Name, " ");
|
|
758
|
+
i0.ɵɵadvance(2);
|
|
759
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(10, 19, ctx.message.__mj_CreatedAt, "short"));
|
|
760
|
+
i0.ɵɵadvance(2);
|
|
761
|
+
i0.ɵɵproperty("ngIf", !ctx.isUserMessage && ctx.formattedGenerationTime && !ctx.isTemporaryMessage);
|
|
762
|
+
i0.ɵɵadvance();
|
|
763
|
+
i0.ɵɵproperty("ngIf", ctx.hasAgentRun);
|
|
764
|
+
i0.ɵɵadvance();
|
|
765
|
+
i0.ɵɵproperty("ngIf", ctx.isUserMessage && ctx.messageStatus !== "Complete");
|
|
766
|
+
i0.ɵɵadvance();
|
|
767
|
+
i0.ɵɵproperty("ngIf", ctx.isTemporaryMessage);
|
|
768
|
+
i0.ɵɵadvance(2);
|
|
769
|
+
i0.ɵɵconditional(!ctx.isEditing ? 16 : -1);
|
|
770
|
+
i0.ɵɵadvance();
|
|
771
|
+
i0.ɵɵconditional(ctx.isEditing ? 17 : -1);
|
|
772
|
+
i0.ɵɵadvance();
|
|
773
|
+
i0.ɵɵconditional(ctx.isAgentDetailsExpanded && ctx.hasAgentRun ? 18 : -1);
|
|
774
|
+
i0.ɵɵadvance();
|
|
775
|
+
i0.ɵɵproperty("ngIf", !ctx.isProcessing && !ctx.isTemporaryMessage && !ctx.isEditing);
|
|
776
|
+
i0.ɵɵadvance();
|
|
777
|
+
i0.ɵɵproperty("ngIf", !ctx.isProcessing && !ctx.isTemporaryMessage && !ctx.isEditing);
|
|
778
|
+
} }, dependencies: [i3.NgClass, i3.NgIf, i4.DefaultValueAccessor, i4.NgControlStatus, i4.NgModel, i5.MarkdownComponent, i3.DatePipe], styles: [".message-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 8px 24px;\n transition: background-color 150ms ease;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n position: relative;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.message-item.ai-message[_ngcontent-%COMP%] {\n background-color: transparent;\n}\n\n.message-item.user-message[_ngcontent-%COMP%] {\n background-color: transparent;\n}\n\n.message-item.pinned[_ngcontent-%COMP%] {\n border-left: 3px solid #0076B6;\n background-color: rgba(0, 118, 182, 0.08);\n}\n\n.message-item.in-progress[_ngcontent-%COMP%] {\n background: linear-gradient(90deg,\n rgba(59, 130, 246, 0.08) 0%,\n rgba(59, 130, 246, 0.12) 50%,\n rgba(59, 130, 246, 0.08) 100%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 2s ease-in-out infinite;\n border-left: 3px solid #3B82F6;\n position: relative;\n}\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n\n\n\n.message-item.in-progress[_ngcontent-%COMP%] .message-text[_ngcontent-%COMP%] {\n color: #1F2937;\n font-weight: 500;\n max-height: 150px;\n overflow-y: auto;\n display: block;\n}\n\n\n\n.message-item.in-progress[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n right: 12px;\n top: 22px;\n width: 16px;\n height: 16px;\n border: 2px solid #3B82F6;\n border-top-color: transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 0.8s linear infinite;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n to { transform: rotate(360deg); }\n}\n\n\n\n.message-item.in-progress[_ngcontent-%COMP%] .avatar-circle[_ngcontent-%COMP%] {\n box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);\n }\n}\n\n.message-item[_ngcontent-%COMP%]:hover {\n background-color: rgba(0, 0, 0, 0.02);\n}\n\n\n\n[_nghost-%COMP%] .mention-badge {\n display: inline-block;\n padding: 2px 8px;\n margin: 0 2px;\n border-radius: 4px;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .mention-badge.agent {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n}\n\n[_nghost-%COMP%] .mention-badge.user {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n}\n\n[_nghost-%COMP%] .mention-badge:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.message-avatar[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.avatar-circle[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: white;\n}\n\n\n\n.avatar-circle.user-avatar[_ngcontent-%COMP%] {\n border-radius: 50%;\n background-color: #333;\n}\n\n\n\n.avatar-circle.ai-avatar[_ngcontent-%COMP%] {\n border-radius: 8px;\n background-color: #9333EA; \n\n}\n\n.message-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n position: relative;\n}\n\n.message-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n font-size: 13px;\n}\n\n.message-sender[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #333;\n}\n\n\n\n.agent-badge[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n background: #F3F4F6;\n border-radius: 10px;\n font-size: 11px;\n color: #6B7280;\n font-weight: 500;\n}\n\n.message-time[_ngcontent-%COMP%] {\n color: #9CA3AF;\n font-size: 12px;\n font-weight: 400;\n}\n\n.generation-time[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: #E0F2FE;\n border-radius: 10px;\n font-size: 11px;\n color: #0369A1;\n font-weight: 500;\n margin-left: auto;\n}\n\n.generation-time[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.message-elapsed[_ngcontent-%COMP%] {\n color: #AAA;\n font-size: 11px;\n font-style: italic;\n}\n\n.message-body[_ngcontent-%COMP%] {\n margin-bottom: 0;\n}\n\n.message-text[_ngcontent-%COMP%] {\n color: #333;\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n\n\n.message-text[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > [_ngcontent-%COMP%]:first-child {\n margin-top: 0;\n}\n\n.message-text[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > [_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n\n\n.message-item.user-message[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n border-radius: 12px 12px 12px 4px;\n}\n\n.message-item.ai-message[_ngcontent-%COMP%] .message-content[_ngcontent-%COMP%] {\n border-radius: 4px 12px 12px 12px;\n}\n\n\n\n.message-reactions[_ngcontent-%COMP%] {\n display: none; \n\n}\n\n\n\n.artifact-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 12px;\n padding: 16px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n border-radius: 8px;\n background: linear-gradient(135deg, #F8F7FF 0%, #F3F2FF 100%);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 500px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n position: relative;\n overflow: hidden;\n}\n\n.artifact-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(180deg, #8B5CF6 0%, #6366F1 100%);\n opacity: 1;\n}\n\n.artifact-card[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #F3F2FF 0%, #EBE9FF 100%);\n border-color: rgba(139, 92, 246, 0.3);\n box-shadow: 0 4px 12px rgba(139, 92, 246, 0.12);\n transform: translateY(-1px);\n}\n\n.artifact-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.artifact-card-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #8B5CF6;\n flex-shrink: 0;\n background: rgba(139, 92, 246, 0.1);\n border-radius: 6px;\n transition: all 0.2s ease;\n}\n\n.artifact-card[_ngcontent-%COMP%]:hover .artifact-card-icon[_ngcontent-%COMP%] {\n background: rgba(139, 92, 246, 0.15);\n transform: scale(1.05);\n}\n\n.artifact-card-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 18px;\n}\n\n.artifact-card-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-card-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #374151;\n letter-spacing: -0.01em;\n margin-bottom: 4px;\n}\n\n.artifact-card-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6B7280;\n line-height: 1.5;\n}\n\n.message-actions[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 8px;\n right: 8px;\n display: flex;\n gap: 2px;\n opacity: 0;\n transform: translateY(4px);\n transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n padding: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n pointer-events: none;\n}\n\n.message-item[_ngcontent-%COMP%]:hover .message-actions[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n.message-action-btn[_ngcontent-%COMP%] {\n padding: 6px 8px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: #6B7280;\n font-size: 13px;\n transition: all 150ms ease;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: 32px;\n}\n\n.message-action-btn[_ngcontent-%COMP%]:hover {\n background-color: #F3F4F6;\n color: #111827;\n}\n\n.message-action-btn.danger[_ngcontent-%COMP%]:hover {\n background-color: #FEE2E2;\n color: #DC2626;\n}\n\n.message-action-btn.retry-btn[_ngcontent-%COMP%] {\n color: #3B82F6;\n background: #EFF6FF;\n font-weight: 600;\n gap: 6px;\n padding: 6px 12px;\n min-width: auto;\n}\n\n.message-action-btn.retry-btn[_ngcontent-%COMP%]:hover {\n background-color: #DBEAFE;\n color: #2563EB;\n}\n\n\n\n.thread-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n margin-top: 8px;\n background: #EFF6FF;\n border: 1px solid #DBEAFE;\n border-radius: 16px;\n cursor: pointer;\n transition: all 150ms ease;\n font-size: 12px;\n color: #1E40AF;\n font-weight: 500;\n}\n\n.thread-indicator[_ngcontent-%COMP%]:hover {\n background: #DBEAFE;\n border-color: #93C5FD;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(30, 64, 175, 0.1);\n}\n\n.thread-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.thread-count[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n\n\n.message-item.editing[_ngcontent-%COMP%] {\n background-color: rgba(255, 243, 205, 0.3);\n border-left: 3px solid #FFA726;\n}\n\n.message-edit-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.message-edit-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid #D9D9D9;\n border-radius: 6px;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.6;\n resize: vertical;\n min-height: 80px;\n transition: border-color 150ms ease;\n}\n\n.message-edit-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #0076B6;\n box-shadow: 0 0 0 2px rgba(0, 118, 182, 0.1);\n}\n\n.edit-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.edit-action-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.edit-action-btn.save[_ngcontent-%COMP%] {\n background-color: #0076B6;\n color: white;\n}\n\n.edit-action-btn.save[_ngcontent-%COMP%]:hover {\n background-color: #005A8F;\n}\n\n.edit-action-btn.cancel[_ngcontent-%COMP%] {\n background-color: #F4F4F4;\n color: #666;\n}\n\n.edit-action-btn.cancel[_ngcontent-%COMP%]:hover {\n background-color: #E0E0E0;\n color: #333;\n}\n\n.edit-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #AAA;\n font-style: italic;\n}\n\n.edited-badge[_ngcontent-%COMP%] {\n margin-left: 8px;\n font-size: 11px;\n color: #AAA;\n font-style: italic;\n font-weight: normal;\n}\n\n\n\n.message-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n color: #6B7280;\n padding: 2px 8px;\n background: #F3F4F6;\n border-radius: 4px;\n margin-left: 8px;\n animation: _ngcontent-%COMP%_statusPulse 2s ease-in-out infinite;\n}\n\n.message-status[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #0076B6;\n font-size: 11px;\n}\n\n.message-status.error[_ngcontent-%COMP%] {\n background: #FEE2E2;\n color: #DC2626;\n}\n\n.message-status.error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #DC2626;\n}\n\n.status-text[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n@keyframes _ngcontent-%COMP%_statusPulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n\n\n\n\n\n\n\n\n.agent-run-icon[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n color: #9CA3AF;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n margin-left: 8px;\n}\n\n.agent-run-icon[_ngcontent-%COMP%] i.fa-cog[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n.agent-run-icon[_ngcontent-%COMP%]:hover {\n color: #6B7280;\n}\n\n.agent-run-icon.expanded[_ngcontent-%COMP%] {\n color: #4B5563;\n}\n\n.agent-run-icon.expanded[_ngcontent-%COMP%] i.fa-cog[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_rotate 1s linear infinite;\n}\n\n@keyframes _ngcontent-%COMP%_rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n\n\n.agent-details-panel[_ngcontent-%COMP%] {\n margin-top: 12px;\n padding: 16px;\n background: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n animation: _ngcontent-%COMP%_slideDown 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.agent-details-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6B7280;\n font-size: 13px;\n}\n\n.agent-details-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #9333EA;\n}\n\n\n\n.agent-details-error[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #DC2626;\n font-size: 13px;\n}\n\n.agent-details-error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #DC2626;\n}\n\n\n\n.agent-details-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 1px solid #E5E7EB;\n font-weight: 600;\n font-size: 13px;\n color: #374151;\n}\n\n.agent-details-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #9333EA;\n}\n\n.agent-name-link[_ngcontent-%COMP%] {\n color: #9333EA;\n cursor: pointer;\n text-decoration: none;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.agent-name-link[_ngcontent-%COMP%]:hover {\n color: #7C3AED;\n text-decoration: underline;\n}\n\n\n\n.agent-details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.detail-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 12px;\n background: white;\n border-radius: 6px;\n border: 1px solid #E5E7EB;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #6B7280;\n font-weight: 500;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #111827;\n font-weight: 600;\n font-family: 'Monaco', 'Menlo', 'Consolas', monospace;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n padding: 3px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-pending[_ngcontent-%COMP%] {\n background: #FEF3C7;\n color: #92400E;\n}\n\n.status-badge.status-running[_ngcontent-%COMP%] {\n background: #DBEAFE;\n color: #1E40AF;\n}\n\n.status-badge.status-complete[_ngcontent-%COMP%] {\n background: #D1FAE5;\n color: #065F46;\n}\n\n.status-badge.status-failed[_ngcontent-%COMP%], \n.status-badge.status-error[_ngcontent-%COMP%] {\n background: #FEE2E2;\n color: #991B1B;\n}\n\n.status-badge.status-cancelled[_ngcontent-%COMP%] {\n background: #F3F4F6;\n color: #4B5563;\n}\n\n\n\n.run-id-link[_ngcontent-%COMP%] {\n color: #3B82F6;\n cursor: pointer;\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n}\n\n.run-id-link[_ngcontent-%COMP%]:hover {\n color: #2563EB;\n text-decoration: underline;\n}\n\n.run-id-link[_ngcontent-%COMP%] i.fa-external-link-alt[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}"] });
|
|
779
|
+
}
|
|
780
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MessageItemComponent, [{
|
|
781
|
+
type: Component,
|
|
782
|
+
args: [{ selector: 'mj-conversation-message-item', template: "<div [class]=\"messageClasses\">\n <div class=\"message-avatar\">\n <div class=\"avatar-circle\" [class.ai-avatar]=\"isAIMessage\" [class.user-avatar]=\"isUserMessage\">\n <i class=\"fas\" [ngClass]=\"isAIMessage ? (aiAgentInfo?.iconClass || 'fa-robot') : 'fa-user'\"></i>\n </div>\n </div>\n\n <div class=\"message-content\">\n <div class=\"message-header\">\n <span class=\"message-sender\" [title]=\"isAIMessage ? (aiAgentInfo?.role || 'AI Assistant') : ''\">\n {{ isAIMessage ? (aiAgentInfo?.name || 'AI Assistant') : currentUser.Name }}\n </span>\n <span class=\"message-time\">{{ message.__mj_CreatedAt | date:'short' }}</span>\n\n <!-- Generation time for completed AI messages -->\n <span *ngIf=\"!isUserMessage && formattedGenerationTime && !isTemporaryMessage\" class=\"generation-time\">\n <i class=\"fas fa-clock\"></i>\n {{ formattedGenerationTime }}\n </span>\n\n <!-- Agent run icon (clickable to expand details) -->\n <span *ngIf=\"hasAgentRun\"\n class=\"agent-run-icon\"\n (click)=\"toggleAgentDetails()\"\n [class.expanded]=\"isAgentDetailsExpanded\"\n title=\"Click to view agent execution details\">\n <i class=\"fas fa-cog\"></i>\n </span>\n\n <!-- Status indicator for user messages -->\n <span *ngIf=\"isUserMessage && messageStatus !== 'Complete'\" class=\"message-status\" [class.error]=\"messageStatus === 'Error'\">\n <i class=\"fas\" [ngClass]=\"messageStatus === 'Error' ? 'fa-exclamation-triangle' : 'fa-circle-notch fa-spin'\"></i>\n <span class=\"status-text\">{{ getStatusText() }}</span>\n </span>\n\n <!-- Elapsed time for AI messages still processing -->\n <span *ngIf=\"isTemporaryMessage\" class=\"message-elapsed\">{{ _elapsedTimeFormatted }}</span>\n </div>\n\n <div class=\"message-body\">\n @if (!isEditing) {\n <div class=\"message-text\">\n <markdown [data]=\"displayMessage\"></markdown>\n @if (isMessageEdited) {\n <span class=\"edited-badge\">(edited)</span>\n }\n </div>\n\n <!-- Artifact Card (Claude.ai Style) -->\n @if (hasArtifact) {\n <div class=\"artifact-card\" (click)=\"onArtifactClick()\">\n <div class=\"artifact-card-header\">\n <div class=\"artifact-card-icon\">\n <i class=\"fas fa-file-code\"></i>\n </div>\n <div class=\"artifact-card-content\">\n <div class=\"artifact-card-label\">Generated Artifact</div>\n <div class=\"artifact-card-description\">Click to view the generated content</div>\n </div>\n </div>\n </div>\n }\n }\n\n @if (isEditing) {\n <div class=\"message-edit-container\">\n <textarea\n class=\"message-edit-textarea\"\n [(ngModel)]=\"editedText\"\n (keydown)=\"onEditKeydown($event)\"\n rows=\"4\"\n placeholder=\"Edit your message...\"></textarea>\n <div class=\"edit-actions\">\n <button class=\"edit-action-btn save\" (click)=\"saveEdit()\">\n <i class=\"fas fa-check\"></i>\n Save\n </button>\n <button class=\"edit-action-btn cancel\" (click)=\"cancelEditing()\">\n <i class=\"fas fa-times\"></i>\n Cancel\n </button>\n </div>\n <div class=\"edit-hint\">\n Press Enter to save, Shift+Enter for new line, Escape to cancel\n </div>\n </div>\n }\n\n <!-- Agent Run Details Panel (expandable) -->\n @if (isAgentDetailsExpanded && hasAgentRun) {\n <div class=\"agent-details-panel\">\n @if (agentRun) {\n <div class=\"agent-details-content\">\n <div class=\"agent-details-header\">\n <i class=\"fas fa-chart-line\"></i>\n <span>\n <a class=\"agent-name-link\" (click)=\"openAgentRecord()\" title=\"Open agent details\">\n {{ aiAgentInfo?.name || 'Agent' }}\n </a>\n Run Details\n </span>\n </div>\n\n <div class=\"agent-details-grid\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Run ID:</span>\n <span class=\"detail-value\">\n <a class=\"run-id-link\" (click)=\"openAgentRunRecord()\" title=\"Open agent run details\">\n {{ agentRun.ID }}\n <i class=\"fas fa-external-link-alt\"></i>\n </a>\n </span>\n </div>\n\n <div class=\"detail-row\" *ngIf=\"agentRunDuration\">\n <span class=\"detail-label\">Duration:</span>\n <span class=\"detail-value\">{{ agentRunDuration }}</span>\n </div>\n\n <div class=\"detail-row\" *ngIf=\"agentRunStepCount > 0\">\n <span class=\"detail-label\">Steps:</span>\n <span class=\"detail-value\">{{ agentRunStepCount }}</span>\n </div>\n\n <div class=\"detail-row\" *ngIf=\"agentRunTotalTokens > 0\">\n <span class=\"detail-label\">Tokens:</span>\n <span class=\"detail-value\">{{ formatNumber(agentRunTotalTokens) }}</span>\n </div>\n\n <div class=\"detail-row\" *ngIf=\"agentRunTotalCost > 0\">\n <span class=\"detail-label\">Cost:</span>\n <span class=\"detail-value\">\\${{ agentRunTotalCost.toFixed(4) }}</span>\n </div>\n\n <div class=\"detail-row\" *ngIf=\"agentRun.Status\">\n <span class=\"detail-label\">Status:</span>\n <span class=\"detail-value status-badge\" [class]=\"'status-' + agentRun.Status.toLowerCase()\">\n {{ agentRun.Status }}\n </span>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"message-actions\" *ngIf=\"!isProcessing && !isTemporaryMessage && !isEditing\">\n <!-- Retry button for failed AI messages -->\n <button class=\"message-action-btn retry-btn\" (click)=\"onRetryClick()\" title=\"Retry\" *ngIf=\"messageStatus === 'Error' && isAIMessage\">\n <i class=\"fas fa-redo\"></i>\n Retry\n </button>\n\n <button class=\"message-action-btn\" (click)=\"onPinClick()\" [title]=\"message.IsPinned ? 'Unpin' : 'Pin'\">\n <i class=\"fas\" [ngClass]=\"message.IsPinned ? 'fa-thumbtack' : 'fa-thumbtack'\"></i>\n </button>\n <button class=\"message-action-btn\" (click)=\"onEditClick()\" title=\"Edit\" *ngIf=\"isUserMessage\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <button class=\"message-action-btn danger\" (click)=\"onDeleteClick()\" title=\"Delete\">\n <i class=\"fas fa-trash\"></i>\n </button>\n </div>\n\n <!-- Reaction Buttons -->\n <div class=\"message-reactions\" *ngIf=\"!isProcessing && !isTemporaryMessage && !isEditing\">\n <button class=\"reaction-btn\" (click)=\"toggleReaction('like')\">\n <i class=\"far fa-thumbs-up\"></i>\n <span class=\"reaction-count\">0</span>\n </button>\n <button class=\"reaction-btn\" (click)=\"toggleReaction('comment')\">\n <i class=\"far fa-comment\"></i>\n <span class=\"reaction-count\">0</span>\n </button>\n </div>\n </div>\n</div>", styles: [".message-item {\n display: flex;\n gap: 12px;\n padding: 8px 24px;\n transition: background-color 150ms ease;\n animation: fadeIn 0.3s ease;\n position: relative;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.message-item.ai-message {\n background-color: transparent;\n}\n\n.message-item.user-message {\n background-color: transparent;\n}\n\n.message-item.pinned {\n border-left: 3px solid #0076B6;\n background-color: rgba(0, 118, 182, 0.08);\n}\n\n.message-item.in-progress {\n background: linear-gradient(90deg,\n rgba(59, 130, 246, 0.08) 0%,\n rgba(59, 130, 246, 0.12) 50%,\n rgba(59, 130, 246, 0.08) 100%);\n background-size: 200% 100%;\n animation: shimmer 2s ease-in-out infinite;\n border-left: 3px solid #3B82F6;\n position: relative;\n}\n\n@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n\n/* Progress message styling - make it visually distinct */\n.message-item.in-progress .message-text {\n color: #1F2937;\n font-weight: 500;\n max-height: 150px;\n overflow-y: auto;\n display: block;\n}\n\n/* Progress icon - positioned to the right of message, pushed down to avoid overlap */\n.message-item.in-progress .message-content::after {\n content: '';\n position: absolute;\n right: 12px;\n top: 22px;\n width: 16px;\n height: 16px;\n border: 2px solid #3B82F6;\n border-top-color: transparent;\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n}\n\n@keyframes spin {\n to { transform: rotate(360deg); }\n}\n\n/* Pulse effect for avatar */\n.message-item.in-progress .avatar-circle {\n box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);\n animation: pulse 2s ease-in-out infinite;\n}\n\n@keyframes pulse {\n 0%, 100% {\n box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.7);\n }\n 50% {\n box-shadow: 0 0 0 8px rgba(59, 130, 246, 0);\n }\n}\n\n.message-item:hover {\n background-color: rgba(0, 0, 0, 0.02);\n}\n\n/* Mention Pills */\n:host ::ng-deep .mention-badge {\n display: inline-block;\n padding: 2px 8px;\n margin: 0 2px;\n border-radius: 4px;\n font-weight: 500;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .mention-badge.agent {\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n}\n\n:host ::ng-deep .mention-badge.user {\n background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);\n color: white;\n}\n\n:host ::ng-deep .mention-badge:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.message-avatar {\n flex-shrink: 0;\n}\n\n.avatar-circle {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n color: white;\n}\n\n/* User avatars are circular */\n.avatar-circle.user-avatar {\n border-radius: 50%;\n background-color: #333;\n}\n\n/* Agent avatars are square with rounded corners */\n.avatar-circle.ai-avatar {\n border-radius: 8px;\n background-color: #9333EA; /* Purple for agents */\n}\n\n.message-content {\n flex: 1;\n min-width: 0;\n position: relative;\n}\n\n.message-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n font-size: 13px;\n}\n\n.message-sender {\n font-weight: 600;\n color: #333;\n}\n\n/* Agent role badge */\n.agent-badge {\n display: inline-block;\n padding: 2px 8px;\n background: #F3F4F6;\n border-radius: 10px;\n font-size: 11px;\n color: #6B7280;\n font-weight: 500;\n}\n\n.message-time {\n color: #9CA3AF;\n font-size: 12px;\n font-weight: 400;\n}\n\n.generation-time {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: #E0F2FE;\n border-radius: 10px;\n font-size: 11px;\n color: #0369A1;\n font-weight: 500;\n margin-left: auto;\n}\n\n.generation-time i {\n font-size: 10px;\n}\n\n.message-elapsed {\n color: #AAA;\n font-size: 11px;\n font-style: italic;\n}\n\n.message-body {\n margin-bottom: 0;\n}\n\n.message-text {\n color: #333;\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n/* Remove extra margin from markdown paragraphs */\n.message-text markdown > :first-child {\n margin-top: 0;\n}\n\n.message-text markdown > :last-child {\n margin-bottom: 0;\n}\n\n/* Asymmetric bubble shapes for message content */\n.message-item.user-message .message-content {\n border-radius: 12px 12px 12px 4px;\n}\n\n.message-item.ai-message .message-content {\n border-radius: 4px 12px 12px 12px;\n}\n\n/* Reaction Buttons */\n.message-reactions {\n display: none; /* Hide reactions for now - not implemented */\n}\n\n/* Artifact Card - Claude.ai Style */\n.artifact-card {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: 12px;\n padding: 16px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n border-radius: 8px;\n background: linear-gradient(135deg, #F8F7FF 0%, #F3F2FF 100%);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n max-width: 500px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n position: relative;\n overflow: hidden;\n}\n\n.artifact-card::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(180deg, #8B5CF6 0%, #6366F1 100%);\n opacity: 1;\n}\n\n.artifact-card:hover {\n background: linear-gradient(135deg, #F3F2FF 0%, #EBE9FF 100%);\n border-color: rgba(139, 92, 246, 0.3);\n box-shadow: 0 4px 12px rgba(139, 92, 246, 0.12);\n transform: translateY(-1px);\n}\n\n.artifact-card-header {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n}\n\n.artifact-card-icon {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #8B5CF6;\n flex-shrink: 0;\n background: rgba(139, 92, 246, 0.1);\n border-radius: 6px;\n transition: all 0.2s ease;\n}\n\n.artifact-card:hover .artifact-card-icon {\n background: rgba(139, 92, 246, 0.15);\n transform: scale(1.05);\n}\n\n.artifact-card-icon i {\n font-size: 18px;\n}\n\n.artifact-card-content {\n flex: 1;\n min-width: 0;\n}\n\n.artifact-card-label {\n font-size: 14px;\n font-weight: 600;\n color: #374151;\n letter-spacing: -0.01em;\n margin-bottom: 4px;\n}\n\n.artifact-card-description {\n font-size: 13px;\n color: #6B7280;\n line-height: 1.5;\n}\n\n.message-actions {\n position: absolute;\n bottom: 8px;\n right: 8px;\n display: flex;\n gap: 2px;\n opacity: 0;\n transform: translateY(4px);\n transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);\n background: white;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n padding: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n pointer-events: none;\n}\n\n.message-item:hover .message-actions {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n.message-action-btn {\n padding: 6px 8px;\n background: transparent;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n color: #6B7280;\n font-size: 13px;\n transition: all 150ms ease;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 32px;\n height: 32px;\n}\n\n.message-action-btn:hover {\n background-color: #F3F4F6;\n color: #111827;\n}\n\n.message-action-btn.danger:hover {\n background-color: #FEE2E2;\n color: #DC2626;\n}\n\n.message-action-btn.retry-btn {\n color: #3B82F6;\n background: #EFF6FF;\n font-weight: 600;\n gap: 6px;\n padding: 6px 12px;\n min-width: auto;\n}\n\n.message-action-btn.retry-btn:hover {\n background-color: #DBEAFE;\n color: #2563EB;\n}\n\n/* Thread indicator badge */\n.thread-indicator {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n margin-top: 8px;\n background: #EFF6FF;\n border: 1px solid #DBEAFE;\n border-radius: 16px;\n cursor: pointer;\n transition: all 150ms ease;\n font-size: 12px;\n color: #1E40AF;\n font-weight: 500;\n}\n\n.thread-indicator:hover {\n background: #DBEAFE;\n border-color: #93C5FD;\n transform: translateY(-1px);\n box-shadow: 0 2px 4px rgba(30, 64, 175, 0.1);\n}\n\n.thread-indicator i {\n font-size: 14px;\n}\n\n.thread-count {\n font-weight: 600;\n}\n\n/* Edit mode styles */\n.message-item.editing {\n background-color: rgba(255, 243, 205, 0.3);\n border-left: 3px solid #FFA726;\n}\n\n.message-edit-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.message-edit-textarea {\n width: 100%;\n padding: 12px;\n border: 1px solid #D9D9D9;\n border-radius: 6px;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.6;\n resize: vertical;\n min-height: 80px;\n transition: border-color 150ms ease;\n}\n\n.message-edit-textarea:focus {\n outline: none;\n border-color: #0076B6;\n box-shadow: 0 0 0 2px rgba(0, 118, 182, 0.1);\n}\n\n.edit-actions {\n display: flex;\n gap: 8px;\n}\n\n.edit-action-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: none;\n border-radius: 6px;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 150ms ease;\n}\n\n.edit-action-btn.save {\n background-color: #0076B6;\n color: white;\n}\n\n.edit-action-btn.save:hover {\n background-color: #005A8F;\n}\n\n.edit-action-btn.cancel {\n background-color: #F4F4F4;\n color: #666;\n}\n\n.edit-action-btn.cancel:hover {\n background-color: #E0E0E0;\n color: #333;\n}\n\n.edit-hint {\n font-size: 12px;\n color: #AAA;\n font-style: italic;\n}\n\n.edited-badge {\n margin-left: 8px;\n font-size: 11px;\n color: #AAA;\n font-style: italic;\n font-weight: normal;\n}\n\n/* Message status indicator */\n.message-status {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n color: #6B7280;\n padding: 2px 8px;\n background: #F3F4F6;\n border-radius: 4px;\n margin-left: 8px;\n animation: statusPulse 2s ease-in-out infinite;\n}\n\n.message-status i {\n color: #0076B6;\n font-size: 11px;\n}\n\n.message-status.error {\n background: #FEE2E2;\n color: #DC2626;\n}\n\n.message-status.error i {\n color: #DC2626;\n}\n\n.status-text {\n font-weight: 500;\n}\n\n@keyframes statusPulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.7; }\n}\n\n/* ============================================\n Agent Run Icon & Details Panel\n ============================================ */\n\n/* Agent run gear icon in header - muted style for power users */\n.agent-run-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n color: #9CA3AF;\n cursor: pointer;\n transition: all 0.2s ease;\n user-select: none;\n margin-left: 8px;\n}\n\n.agent-run-icon i.fa-cog {\n font-size: 13px;\n}\n\n.agent-run-icon:hover {\n color: #6B7280;\n}\n\n.agent-run-icon.expanded {\n color: #4B5563;\n}\n\n.agent-run-icon.expanded i.fa-cog {\n animation: rotate 1s linear infinite;\n}\n\n@keyframes rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Agent details panel */\n.agent-details-panel {\n margin-top: 12px;\n padding: 16px;\n background: #F9FAFB;\n border: 1px solid #E5E7EB;\n border-radius: 8px;\n animation: slideDown 0.2s ease;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Loading state */\n.agent-details-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #6B7280;\n font-size: 13px;\n}\n\n.agent-details-loading i {\n color: #9333EA;\n}\n\n/* Error state */\n.agent-details-error {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #DC2626;\n font-size: 13px;\n}\n\n.agent-details-error i {\n color: #DC2626;\n}\n\n/* Content header */\n.agent-details-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 12px;\n padding-bottom: 8px;\n border-bottom: 1px solid #E5E7EB;\n font-weight: 600;\n font-size: 13px;\n color: #374151;\n}\n\n.agent-details-header i {\n color: #9333EA;\n}\n\n.agent-name-link {\n color: #9333EA;\n cursor: pointer;\n text-decoration: none;\n font-weight: 600;\n transition: all 0.2s ease;\n}\n\n.agent-name-link:hover {\n color: #7C3AED;\n text-decoration: underline;\n}\n\n/* Details grid */\n.agent-details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 12px;\n margin-bottom: 12px;\n}\n\n.detail-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 8px 12px;\n background: white;\n border-radius: 6px;\n border: 1px solid #E5E7EB;\n}\n\n.detail-label {\n font-size: 12px;\n color: #6B7280;\n font-weight: 500;\n}\n\n.detail-value {\n font-size: 13px;\n color: #111827;\n font-weight: 600;\n font-family: 'Monaco', 'Menlo', 'Consolas', monospace;\n}\n\n/* Status badge in details */\n.status-badge {\n padding: 3px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-pending {\n background: #FEF3C7;\n color: #92400E;\n}\n\n.status-badge.status-running {\n background: #DBEAFE;\n color: #1E40AF;\n}\n\n.status-badge.status-complete {\n background: #D1FAE5;\n color: #065F46;\n}\n\n.status-badge.status-failed,\n.status-badge.status-error {\n background: #FEE2E2;\n color: #991B1B;\n}\n\n.status-badge.status-cancelled {\n background: #F3F4F6;\n color: #4B5563;\n}\n\n/* Run ID link styling */\n.run-id-link {\n color: #3B82F6;\n cursor: pointer;\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n transition: all 0.2s ease;\n}\n\n.run-id-link:hover {\n color: #2563EB;\n text-decoration: underline;\n}\n\n.run-id-link i.fa-external-link-alt {\n font-size: 10px;\n opacity: 0.7;\n}"] }]
|
|
783
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i1.MentionParserService }, { type: i2.MentionAutocompleteService }], { message: [{
|
|
784
|
+
type: Input
|
|
785
|
+
}], conversation: [{
|
|
786
|
+
type: Input
|
|
787
|
+
}], currentUser: [{
|
|
788
|
+
type: Input
|
|
789
|
+
}], allMessages: [{
|
|
790
|
+
type: Input
|
|
791
|
+
}], isProcessing: [{
|
|
792
|
+
type: Input
|
|
793
|
+
}], artifactId: [{
|
|
794
|
+
type: Input
|
|
795
|
+
}], artifactVersionId: [{
|
|
796
|
+
type: Input
|
|
797
|
+
}], agentRun: [{
|
|
798
|
+
type: Input
|
|
799
|
+
}], pinClicked: [{
|
|
800
|
+
type: Output
|
|
801
|
+
}], editClicked: [{
|
|
802
|
+
type: Output
|
|
803
|
+
}], deleteClicked: [{
|
|
804
|
+
type: Output
|
|
805
|
+
}], retryClicked: [{
|
|
806
|
+
type: Output
|
|
807
|
+
}], artifactClicked: [{
|
|
808
|
+
type: Output
|
|
809
|
+
}], artifactActionPerformed: [{
|
|
810
|
+
type: Output
|
|
811
|
+
}], messageEdited: [{
|
|
812
|
+
type: Output
|
|
813
|
+
}], openEntityRecord: [{
|
|
814
|
+
type: Output
|
|
815
|
+
}] }); })();
|
|
816
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MessageItemComponent, { className: "MessageItemComponent", filePath: "src/lib/components/message/message-item.component.ts", lineNumber: 28 }); })();
|
|
817
|
+
//# sourceMappingURL=message-item.component.js.map
|