max-agent-ui 0.0.10 → 0.0.11
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.
|
@@ -16,6 +16,32 @@ import { TooltipModule } from 'primeng/tooltip';
|
|
|
16
16
|
import { HttpClient } from '@angular/common/http';
|
|
17
17
|
import { throwError } from 'rxjs';
|
|
18
18
|
|
|
19
|
+
const DEFAULT_ASSISTANT_BOOTSTRAP = {
|
|
20
|
+
initialMessage: undefined,
|
|
21
|
+
initialSuggestions: []
|
|
22
|
+
};
|
|
23
|
+
const ASSISTANT_BOOTSTRAP_BY_APP = {
|
|
24
|
+
cortex: {
|
|
25
|
+
initialMessage: 'Hi, I am Max, the Maxtime Virtual Assistant. How can I help you today?',
|
|
26
|
+
initialSuggestions: ['Show my timetable', 'Open scheduling', 'View reports']
|
|
27
|
+
},
|
|
28
|
+
nemesys: {
|
|
29
|
+
initialMessage: 'Hi, I am Max, the Maxtime Virtual Assistant. How can I help you today?',
|
|
30
|
+
initialSuggestions: ['Show scheduling plans', 'Check resource availability', 'Find conflicts']
|
|
31
|
+
},
|
|
32
|
+
attendance: {
|
|
33
|
+
initialMessage: 'Hi, I am Max, the Maxtime Virtual Assistant. How can I help you today?',
|
|
34
|
+
initialSuggestions: ['Show attendance summary', 'Find missing attendance', 'View reports']
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
function getAssistantBootstrapConfig(app) {
|
|
38
|
+
const appKey = app?.trim().toLowerCase();
|
|
39
|
+
if (!appKey) {
|
|
40
|
+
return DEFAULT_ASSISTANT_BOOTSTRAP;
|
|
41
|
+
}
|
|
42
|
+
return ASSISTANT_BOOTSTRAP_BY_APP[appKey] ?? DEFAULT_ASSISTANT_BOOTSTRAP;
|
|
43
|
+
}
|
|
44
|
+
|
|
19
45
|
const MAX_ASSISTANT_CONFIG = new InjectionToken('MAX_ASSISTANT_CONFIG', {
|
|
20
46
|
factory: () => ({})
|
|
21
47
|
});
|
|
@@ -76,15 +102,10 @@ const ASSISTANT_UI_COPY = {
|
|
|
76
102
|
typingLabel: 'Maxtime virtual assistant is typing',
|
|
77
103
|
errorMessage: 'Maxtime virtual assistant could not be reached. Please try again.'
|
|
78
104
|
};
|
|
79
|
-
const DEFAULT_ASSISTANT_BOOTSTRAP = {
|
|
80
|
-
initialMessage: undefined,
|
|
81
|
-
initialSuggestions: []
|
|
82
|
-
};
|
|
83
105
|
class MaxAssistantComponent {
|
|
84
106
|
messagesViewport;
|
|
85
107
|
app;
|
|
86
108
|
user = {};
|
|
87
|
-
initialConfig = {};
|
|
88
109
|
panelVisible = signal(false, ...(ngDevMode ? [{ debugName: "panelVisible" }] : /* istanbul ignore next */ []));
|
|
89
110
|
isSending = signal(false, ...(ngDevMode ? [{ debugName: "isSending" }] : /* istanbul ignore next */ []));
|
|
90
111
|
input = signal('', ...(ngDevMode ? [{ debugName: "input" }] : /* istanbul ignore next */ []));
|
|
@@ -106,11 +127,7 @@ class MaxAssistantComponent {
|
|
|
106
127
|
return ASSISTANT_UI_COPY;
|
|
107
128
|
}
|
|
108
129
|
get bootstrapConfig() {
|
|
109
|
-
return
|
|
110
|
-
...DEFAULT_ASSISTANT_BOOTSTRAP,
|
|
111
|
-
initialMessage: this.initialConfig.initialMessage,
|
|
112
|
-
initialSuggestions: this.initialConfig.initialSuggestions ?? []
|
|
113
|
-
};
|
|
130
|
+
return getAssistantBootstrapConfig(this.app);
|
|
114
131
|
}
|
|
115
132
|
closePanel() {
|
|
116
133
|
this.panelVisible.set(false);
|
|
@@ -256,7 +273,7 @@ class MaxAssistantComponent {
|
|
|
256
273
|
});
|
|
257
274
|
}
|
|
258
275
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: MaxAssistantComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
259
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: MaxAssistantComponent, isStandalone: true, selector: "max-assistant", inputs: { app: "app", user: "user", initialConfig: "initialConfig" }, viewQueries: [{ propertyName: "messagesViewport", first: true, predicate: ["messagesViewport"], descendants: true }], ngImport: i0, template: "<button\n pButton\n type=\"button\"\n class=\"assistant-launcher\"\n [attr.aria-label]=\"uiCopy.launcherLabel\"\n [pTooltip]=\"uiCopy.openTooltip\"\n tooltipPosition=\"left\"\n (click)=\"openPanel()\"\n>\n <span class=\"mascot\" aria-hidden=\"true\"></span>\n</button>\n\n<p-drawer\n [visible]=\"panelVisible()\"\n (visibleChange)=\"panelVisible.set($event)\"\n position=\"right\"\n styleClass=\"assistant-drawer\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n [showCloseIcon]=\"false\"\n>\n <section class=\"assistant-panel\" [attr.aria-label]=\"uiCopy.title\">\n <header class=\"assistant-header\">\n <span class=\"mascot large\" aria-hidden=\"true\"></span>\n <div>\n <h2>{{ uiCopy.title }}</h2>\n <span>{{ uiCopy.subtitle }}</span>\n </div>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-times\"\n text\n rounded\n severity=\"secondary\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n (click)=\"closePanel()\"\n ></button>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article class=\"message {{ message.role }}\" [class.error]=\"message.isError\">\n @if(message.displayResponse; as responseDetails) {\n <p class=\"assistant-result\">{{ responseDetails.agentInferredResponse || message.content }}</p>\n <button\n type=\"button\"\n class=\"inference-toggle\"\n [attr.aria-expanded]=\"isInferenceDetailsVisible(message.id)\"\n (click)=\"toggleInferenceDetails(message.id)\"\n >\n {{ isInferenceDetailsVisible(message.id) ? 'Hide Details' : 'Show Details' }}\n </button>\n\n @if(isInferenceDetailsVisible(message.id)) {\n <div class=\"response-details\">\n @if(responseDetails.userQuery) {\n <section class=\"response-section\">\n <h3>User Query</h3>\n <p class=\"quoted\">\"{{ responseDetails.userQuery }}\"</p>\n </section>\n }\n\n @if(responseDetails.agentExtractedIntent; as intent) {\n <section class=\"response-section\">\n <h3>Agent Extracted Intent</h3>\n <dl class=\"detail-grid\">\n @if(intent.project || intent.projectKey) {\n <div>\n <dt>Project</dt>\n <dd>\n {{ intent.project || intent.projectKey }}\n @if(intent.projectKey) {\n <span>{{ intent.projectKey }}</span>\n }\n </dd>\n </div>\n }\n @if(intent.module) {\n <div>\n <dt>Module</dt>\n <dd>{{ intent.module }}</dd>\n </div>\n }\n @if(intent.intentLabel) {\n <div>\n <dt>Intent Label</dt>\n <dd>{{ intent.intentLabel }}</dd>\n </div>\n }\n @if(intent.intent) {\n <div>\n <dt>Intent</dt>\n <dd>{{ intent.intent }}</dd>\n </div>\n }\n @if(intent.confidence !== undefined) {\n <div>\n <dt>Confidence</dt>\n <dd>{{ intent.confidence | percent: '1.0-0' }}</dd>\n </div>\n }\n </dl>\n\n @if(message.formattedParameters) {\n <div class=\"json-block\">\n <strong>Parameters</strong>\n <pre>{{ message.formattedParameters }}</pre>\n </div>\n }\n\n @if(intent.api?.url || intent.api?.method) {\n <div class=\"api-call-summary\">\n <strong>API Called</strong>\n <code>{{ intent.api?.method || 'GET' }} {{ intent.api?.url || 'URL not provided' }}</code>\n </div>\n }\n\n @if(message.formattedApiBody) {\n <div class=\"json-block\">\n <strong>API Body</strong>\n <pre>{{ message.formattedApiBody }}</pre>\n </div>\n }\n </section>\n }\n\n @if(message.formattedApiResponse) {\n <section class=\"response-section\">\n <h3>API Response</h3>\n <div class=\"json-block\">\n <strong>JSON</strong>\n <pre>{{ message.formattedApiResponse }}</pre>\n </div>\n </section>\n }\n </div>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestion\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n </article>\n }\n @if(isSending()) {\n <article class=\"message assistant typing\" [attr.aria-label]=\"uiCopy.typingLabel\">\n <span></span>\n <span></span>\n <span></span>\n </article>\n }\n </div>\n\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n pTextarea\n name=\"assistantPrompt\"\n rows=\"2\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </section>\n</p-drawer>\n", styles: [":host{position:fixed;right:24px;bottom:24px;z-index:1100}.assistant-launcher{width:70px!important;height:56px!important;min-height:60px!important;padding:0 5px;border:0!important;border-radius:18px!important;color:inherit!important;background:#d7edff!important;box-shadow:0 0 0 1px #0078c824,0 10px 24px #0f172a24!important;overflow:visible}.assistant-launcher:hover,.assistant-launcher:focus-visible{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 12px 28px #0f172a29!important}.mascot{position:relative;display:grid;place-items:center;width:64px;height:56px;background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"120\" height=\"96\" viewBox=\"14 10 92 82\" role=\"img\" aria-label=\"Max smiling cloud AI mascot\">%0A <defs>%0A <filter id=\"softShadow\" x=\"-15%\" y=\"-15%\" width=\"130%\" height=\"140%\">%0A <feDropShadow dx=\"0\" dy=\"5\" stdDeviation=\"5\" flood-color=\"%230078C8\" flood-opacity=\"0.16\"/>%0A </filter>%0A </defs>%0A%0A <g fill=\"%230078C8\" opacity=\"0.28\">%0A <circle cx=\"34\" cy=\"57\" r=\"24\"/>%0A <circle cx=\"58\" cy=\"39\" r=\"31\"/>%0A <circle cx=\"86\" cy=\"58\" r=\"25\"/>%0A <rect x=\"28\" y=\"55\" width=\"68\" height=\"27\" rx=\"13.5\"/>%0A </g>%0A%0A <g fill=\"%230078C8\" opacity=\"0.68\" filter=\"url(%23softShadow)\">%0A <circle cx=\"35\" cy=\"59\" r=\"20\"/>%0A <circle cx=\"59\" cy=\"43\" r=\"27\"/>%0A <circle cx=\"84\" cy=\"60\" r=\"21\"/>%0A <rect x=\"31\" y=\"57\" width=\"64\" height=\"24\" rx=\"12\"/>%0A </g>%0A%0A <g fill=\"%23FFD54A\">%0A <path d=\"M46 48l3.4 6.8 6.8 3.4-6.8 3.4L46 68.4l-3.4-6.8-6.8-3.4 6.8-3.4z\"/>%0A <path d=\"M74 48l3.4 6.8 6.8 3.4-6.8 3.4-3.4 6.8-3.4-6.8-6.8-3.4 6.8-3.4z\"/>%0A <path d=\"M88 28l2 4 4 2-4 2-2 4-2-4-4-2 4-2z\"/>%0A </g>%0A%0A <path%0A d=\"M49 72c6 7 20 7 26 0\"%0A fill=\"none\"%0A stroke=\"%23FFD54A\"%0A stroke-width=\"4\"%0A stroke-linecap=\"round\"%0A />%0A</svg>%0A') center/contain no-repeat}.mascot.large{width:58px;height:46px}::ng-deep .assistant-drawer{width:min(560px,100vw)!important}::ng-deep .assistant-drawer .p-drawer-content{padding:0}::ng-deep .assistant-drawer .p-drawer-header{display:none}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;background:var(--background-color, #f8fafc)}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px;background:#fff;border-bottom:1px solid var(--border-color, #e2e8f0)}.assistant-header h2{margin:0;font-size:20px}.assistant-header span,.sources span{color:#64748b;font-size:12px;font-weight:700}.assistant-header button{margin-left:auto}.assistant-messages{min-height:0;overflow:auto;padding:18px}.message{width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--medium-border-radius, 8px);background:#fff;box-shadow:0 6px 18px #0f172a0f}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--primary-color, #2563eb)}.message.error{border-color:var(--danger-color, #dc2626)}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.inference-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.inference-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.inference-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.suggestion-chip{border:1px solid rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-dark-color, #1d4ed8);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);font-weight:700;box-shadow:0 4px 14px #0f172a0f;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.suggestion-chip:hover{border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.42);color:var(--primary-dark-color, #1d4ed8);background:rgba(var(--primary-color-rgb, 37, 99, 235),.14)}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:800}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:800;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary strong,.json-block strong{color:#64748b;font-size:11px;font-weight:800;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:800;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.typing{display:flex;width:fit-content;max-width:fit-content;gap:5px;align-items:center;padding:4px 0;border:0;background:transparent;box-shadow:none}.typing span{width:7px;height:7px;border-radius:50%;background:var(--primary-color, #2563eb);animation:typing-dot .85s infinite ease-in-out}.typing span:nth-child(2){animation-delay:.15s}.assistant-composer{border-top:1px solid var(--border-color, #e2e8f0);border-bottom:0}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;resize:vertical}@keyframes typing-dot{0%,80%,to{opacity:.35;transform:translateY(0)}40%{opacity:1;transform:translateY(-4px)}}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media(max-width:640px){:host{right:16px;bottom:16px}.assistant-launcher{width:62px!important;min-width:62px!important;height:54px!important;min-height:54px!important}.assistant-messages{padding:14px}.detail-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i3.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i6.PercentPipe, name: "percent" }] });
|
|
276
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: MaxAssistantComponent, isStandalone: true, selector: "max-assistant", inputs: { app: "app", user: "user" }, viewQueries: [{ propertyName: "messagesViewport", first: true, predicate: ["messagesViewport"], descendants: true }], ngImport: i0, template: "<button\n pButton\n type=\"button\"\n class=\"assistant-launcher\"\n [attr.aria-label]=\"uiCopy.launcherLabel\"\n [pTooltip]=\"uiCopy.openTooltip\"\n tooltipPosition=\"left\"\n (click)=\"openPanel()\"\n>\n <span class=\"mascot\" aria-hidden=\"true\"></span>\n</button>\n\n<p-drawer\n [visible]=\"panelVisible()\"\n (visibleChange)=\"panelVisible.set($event)\"\n position=\"right\"\n styleClass=\"assistant-drawer\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n [showCloseIcon]=\"false\"\n>\n <section class=\"assistant-panel\" [attr.aria-label]=\"uiCopy.title\">\n <header class=\"assistant-header\">\n <span class=\"mascot large\" aria-hidden=\"true\"></span>\n <div>\n <h2>{{ uiCopy.title }}</h2>\n <span>{{ uiCopy.subtitle }}</span>\n </div>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-times\"\n text\n rounded\n severity=\"secondary\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n (click)=\"closePanel()\"\n ></button>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article class=\"message {{ message.role }}\" [class.error]=\"message.isError\">\n @if(message.displayResponse; as responseDetails) {\n <p class=\"assistant-result\">{{ responseDetails.agentInferredResponse || message.content }}</p>\n <button\n type=\"button\"\n class=\"inference-toggle\"\n [attr.aria-expanded]=\"isInferenceDetailsVisible(message.id)\"\n (click)=\"toggleInferenceDetails(message.id)\"\n >\n {{ isInferenceDetailsVisible(message.id) ? 'Hide Details' : 'Show Details' }}\n </button>\n\n @if(isInferenceDetailsVisible(message.id)) {\n <div class=\"response-details\">\n @if(responseDetails.userQuery) {\n <section class=\"response-section\">\n <h3>User Query</h3>\n <p class=\"quoted\">\"{{ responseDetails.userQuery }}\"</p>\n </section>\n }\n\n @if(responseDetails.agentExtractedIntent; as intent) {\n <section class=\"response-section\">\n <h3>Agent Extracted Intent</h3>\n <dl class=\"detail-grid\">\n @if(intent.project || intent.projectKey) {\n <div>\n <dt>Project</dt>\n <dd>\n {{ intent.project || intent.projectKey }}\n @if(intent.projectKey) {\n <span>{{ intent.projectKey }}</span>\n }\n </dd>\n </div>\n }\n @if(intent.module) {\n <div>\n <dt>Module</dt>\n <dd>{{ intent.module }}</dd>\n </div>\n }\n @if(intent.intentLabel) {\n <div>\n <dt>Intent Label</dt>\n <dd>{{ intent.intentLabel }}</dd>\n </div>\n }\n @if(intent.intent) {\n <div>\n <dt>Intent</dt>\n <dd>{{ intent.intent }}</dd>\n </div>\n }\n @if(intent.confidence !== undefined) {\n <div>\n <dt>Confidence</dt>\n <dd>{{ intent.confidence | percent: '1.0-0' }}</dd>\n </div>\n }\n </dl>\n\n @if(message.formattedParameters) {\n <div class=\"json-block\">\n <strong>Parameters</strong>\n <pre>{{ message.formattedParameters }}</pre>\n </div>\n }\n\n @if(intent.api?.url || intent.api?.method) {\n <div class=\"api-call-summary\">\n <strong>API Called</strong>\n <code>{{ intent.api?.method || 'GET' }} {{ intent.api?.url || 'URL not provided' }}</code>\n </div>\n }\n\n @if(message.formattedApiBody) {\n <div class=\"json-block\">\n <strong>API Body</strong>\n <pre>{{ message.formattedApiBody }}</pre>\n </div>\n }\n </section>\n }\n\n @if(message.formattedApiResponse) {\n <section class=\"response-section\">\n <h3>API Response</h3>\n <div class=\"json-block\">\n <strong>JSON</strong>\n <pre>{{ message.formattedApiResponse }}</pre>\n </div>\n </section>\n }\n </div>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestion\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n </article>\n }\n @if(isSending()) {\n <article class=\"message assistant typing\" [attr.aria-label]=\"uiCopy.typingLabel\">\n <span></span>\n <span></span>\n <span></span>\n </article>\n }\n </div>\n\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n pTextarea\n name=\"assistantPrompt\"\n rows=\"2\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </section>\n</p-drawer>\n", styles: [":host{position:fixed;right:24px;bottom:24px;z-index:1100}.assistant-launcher{width:70px!important;height:56px!important;min-height:60px!important;padding:0 5px;border:0!important;border-radius:18px!important;color:inherit!important;background:#d7edff!important;box-shadow:0 0 0 1px #0078c824,0 10px 24px #0f172a24!important;overflow:visible}.assistant-launcher:hover,.assistant-launcher:focus-visible{background:#fff!important;box-shadow:0 0 0 2px #0078c838,0 12px 28px #0f172a29!important}.mascot{position:relative;display:grid;place-items:center;width:64px;height:56px;background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"120\" height=\"96\" viewBox=\"14 10 92 82\" role=\"img\" aria-label=\"Max smiling cloud AI mascot\">%0A <defs>%0A <filter id=\"softShadow\" x=\"-15%\" y=\"-15%\" width=\"130%\" height=\"140%\">%0A <feDropShadow dx=\"0\" dy=\"5\" stdDeviation=\"5\" flood-color=\"%230078C8\" flood-opacity=\"0.16\"/>%0A </filter>%0A </defs>%0A%0A <g fill=\"%230078C8\" opacity=\"0.28\">%0A <circle cx=\"34\" cy=\"57\" r=\"24\"/>%0A <circle cx=\"58\" cy=\"39\" r=\"31\"/>%0A <circle cx=\"86\" cy=\"58\" r=\"25\"/>%0A <rect x=\"28\" y=\"55\" width=\"68\" height=\"27\" rx=\"13.5\"/>%0A </g>%0A%0A <g fill=\"%230078C8\" opacity=\"0.68\" filter=\"url(%23softShadow)\">%0A <circle cx=\"35\" cy=\"59\" r=\"20\"/>%0A <circle cx=\"59\" cy=\"43\" r=\"27\"/>%0A <circle cx=\"84\" cy=\"60\" r=\"21\"/>%0A <rect x=\"31\" y=\"57\" width=\"64\" height=\"24\" rx=\"12\"/>%0A </g>%0A%0A <g fill=\"%23FFD54A\">%0A <path d=\"M46 48l3.4 6.8 6.8 3.4-6.8 3.4L46 68.4l-3.4-6.8-6.8-3.4 6.8-3.4z\"/>%0A <path d=\"M74 48l3.4 6.8 6.8 3.4-6.8 3.4-3.4 6.8-3.4-6.8-6.8-3.4 6.8-3.4z\"/>%0A <path d=\"M88 28l2 4 4 2-4 2-2 4-2-4-4-2 4-2z\"/>%0A </g>%0A%0A <path%0A d=\"M49 72c6 7 20 7 26 0\"%0A fill=\"none\"%0A stroke=\"%23FFD54A\"%0A stroke-width=\"4\"%0A stroke-linecap=\"round\"%0A />%0A</svg>%0A') center/contain no-repeat}.mascot.large{width:58px;height:46px}::ng-deep .assistant-drawer{width:min(560px,100vw)!important}::ng-deep .assistant-drawer .p-drawer-content{padding:0}::ng-deep .assistant-drawer .p-drawer-header{display:none}.assistant-panel{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0;background:var(--background-color, #f8fafc)}.assistant-header,.assistant-composer{display:flex;gap:12px;align-items:center;padding:16px;background:#fff;border-bottom:1px solid var(--border-color, #e2e8f0)}.assistant-header h2{margin:0;font-size:20px}.assistant-header span,.sources span{color:#64748b;font-size:12px;font-weight:700}.assistant-header button{margin-left:auto}.assistant-messages{min-height:0;overflow:auto;padding:18px}.message{width:fit-content;max-width:92%;margin-bottom:14px;padding:12px;border:1px solid var(--border-color, #e2e8f0);border-radius:var(--medium-border-radius, 8px);background:#fff;box-shadow:0 6px 18px #0f172a0f}.message.assistant{width:100%;max-width:100%}.message.user{width:fit-content;max-width:88%;margin-left:auto;color:#fff;background:var(--primary-color, #2563eb);border-color:var(--primary-color, #2563eb)}.message.error{border-color:var(--danger-color, #dc2626)}.message p{margin:0;line-height:1.45}.assistant-result{color:#1e293b}.inference-toggle{display:flex;width:fit-content;margin:10px 0 0 auto;padding:0;border:0;color:var(--primary-color, #2563eb);background:transparent;font:inherit;font-size:13px;font-weight:400;text-decoration:underline;text-underline-offset:3px;cursor:pointer}.inference-toggle:hover{color:var(--primary-dark-color, #1d4ed8)}.inference-toggle:focus-visible{outline:2px solid var(--primary-color, #2563eb);outline-offset:3px}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.suggestion-chip{border:1px solid rgba(var(--primary-color-rgb, 37, 99, 235),.28);color:var(--primary-dark-color, #1d4ed8);background:rgba(var(--primary-color-rgb, 37, 99, 235),.08);font-weight:700;box-shadow:0 4px 14px #0f172a0f;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.suggestion-chip:hover{border-color:rgba(var(--primary-color-rgb, 37, 99, 235),.42);color:var(--primary-dark-color, #1d4ed8);background:rgba(var(--primary-color-rgb, 37, 99, 235),.14)}.response-details{display:grid;gap:12px;margin-top:12px}.response-section{display:grid;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--border-color, #e2e8f0)}.response-section:last-child{padding-bottom:0;border-bottom:0}.response-section h3{margin:0;color:#0f172a;font-size:13px;font-weight:800}.quoted{padding:8px 10px;border-left:5px solid var(--primary-color, #2563eb);border-radius:var(--border-radius, 6px);color:#1e293b;background:#f8fafc}.detail-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.detail-grid div{min-width:0;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.detail-grid dt{margin-bottom:3px;color:#64748b;font-size:11px;font-weight:800;text-transform:uppercase}.detail-grid dd{margin:0;color:#334155;font-size:13px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.detail-grid dd span{display:block;margin-top:2px;color:#64748b;font-size:11px}.api-call-summary,.json-block{display:grid;gap:6px;padding:8px;border-radius:var(--border-radius, 6px);background:#f8fafc}.api-call-summary strong,.json-block strong{color:#64748b;font-size:11px;font-weight:800;text-transform:uppercase}.api-call-summary code{color:var(--secondary-color, #0f172a);font-weight:800;white-space:normal;word-break:break-word}.json-block pre{max-height:220px;margin:0;overflow:auto;color:#0f172a;font-size:12px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}.typing{display:flex;width:fit-content;max-width:fit-content;gap:5px;align-items:center;padding:4px 0;border:0;background:transparent;box-shadow:none}.typing span{width:7px;height:7px;border-radius:50%;background:var(--primary-color, #2563eb);animation:typing-dot .85s infinite ease-in-out}.typing span:nth-child(2){animation-delay:.15s}.assistant-composer{border-top:1px solid var(--border-color, #e2e8f0);border-bottom:0}.assistant-composer textarea{flex:1;min-height:46px;max-height:120px;resize:vertical}@keyframes typing-dot{0%,80%,to{opacity:.35;transform:translateY(0)}40%{opacity:1;transform:translateY(-4px)}}@keyframes pulse{to{opacity:.35;transform:translateY(-2px)}}@media(max-width:640px){:host{right:16px;bottom:16px}.assistant-launcher{width:62px!important;min-width:62px!important;height:54px!important;min-height:54px!important}.assistant-messages{padding:14px}.detail-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: DrawerModule }, { kind: "component", type: i3.Drawer, selector: "p-drawer", inputs: ["appendTo", "motionOptions", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "closeButtonProps", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen", "header", "maskStyle", "closable"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "pipe", type: i6.PercentPipe, name: "percent" }] });
|
|
260
277
|
}
|
|
261
278
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: MaxAssistantComponent, decorators: [{
|
|
262
279
|
type: Component,
|
|
@@ -268,8 +285,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImpo
|
|
|
268
285
|
type: Input
|
|
269
286
|
}], user: [{
|
|
270
287
|
type: Input
|
|
271
|
-
}], initialConfig: [{
|
|
272
|
-
type: Input
|
|
273
288
|
}] } });
|
|
274
289
|
|
|
275
290
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"max-agent-ui.mjs","sources":["../../../projects/max-agent-ui/src/lib/config/assistant.config.ts","../../../projects/max-agent-ui/src/lib/components/assistant/max-assistant.service.ts","../../../projects/max-agent-ui/src/lib/components/assistant/max-assistant.component.ts","../../../projects/max-agent-ui/src/lib/components/assistant/max-assistant.component.html","../../../projects/max-agent-ui/src/public-api.ts","../../../projects/max-agent-ui/src/max-agent-ui.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nimport { AssistantProduct, AssistantUser } from '../models/assistant.models';\n\nexport interface MaxAssistantConfig {\n assistantApiUrl?: string;\n app?: AssistantProduct;\n user?: Partial<AssistantUser> | (() => Partial<AssistantUser>);\n}\n\nexport const MAX_ASSISTANT_CONFIG = new InjectionToken<MaxAssistantConfig>(\n 'MAX_ASSISTANT_CONFIG',\n {\n factory: () => ({})\n }\n);\n","import { HttpClient } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { Observable, throwError } from 'rxjs';\n\nimport { MAX_ASSISTANT_CONFIG, MaxAssistantConfig } from '../../config/assistant.config';\nimport {\n AssistantChatRequest,\n AssistantChatResponse,\n AssistantProduct,\n AssistantUser\n} from '../../models/assistant.models';\n\nconst DEFAULT_ASSISTANT_CHAT_URL =\n 'https://fhmaof3b4kaxqfbnomfstxyhw40rrcjr.lambda-url.eu-west-2.on.aws/chat';\nconst DEFAULT_APP = 'assistant';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MaxAssistantService {\n private readonly config = inject(MAX_ASSISTANT_CONFIG);\n private readonly http = inject(HttpClient, { optional: true });\n\n sendMessage(\n message: string,\n conversationId?: string,\n config: MaxAssistantConfig = {}\n ): Observable<AssistantChatResponse> {\n const assistantConfig = {\n ...this.config,\n ...config\n };\n const request: AssistantChatRequest = {\n message,\n conversationId,\n app: this.getApp(assistantConfig),\n user: this.getUser(assistantConfig)\n };\n\n return this.postMessage(request, assistantConfig);\n }\n\n private postMessage(\n request: AssistantChatRequest,\n config: MaxAssistantConfig\n ): Observable<AssistantChatResponse> {\n if (!this.http) {\n return throwError(\n () => new Error('HttpClient is not available. Add provideHttpClient() to the host app.')\n );\n }\n\n return this.http.post<AssistantChatResponse>(this.getChatUrl(config), request);\n }\n\n private getChatUrl(config: MaxAssistantConfig): string {\n return config.assistantApiUrl?.trim() || DEFAULT_ASSISTANT_CHAT_URL;\n }\n\n private getApp(config: MaxAssistantConfig): AssistantProduct {\n return config.app || DEFAULT_APP;\n }\n\n private getUser(config: MaxAssistantConfig): AssistantUser {\n if (typeof config.user === 'function') {\n return config.user();\n }\n\n return config.user ?? {};\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, DestroyRef, ElementRef, inject, Input, signal, ViewChild } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\nimport { ButtonModule } from 'primeng/button';\nimport { DrawerModule } from 'primeng/drawer';\nimport { TextareaModule } from 'primeng/textarea';\nimport { TooltipModule } from 'primeng/tooltip';\n\nimport { MaxAssistantConfig } from '../../config/assistant.config';\nimport {\n AssistantChatResponse,\n AssistantDisplayResponse,\n AssistantExtractedIntent,\n AssistantFieldMap,\n AssistantMessage,\n AssistantProduct,\n AssistantUser,\n InitialConfig\n} from '../../models/assistant.models';\nimport { MaxAssistantService } from './max-assistant.service';\n\nconst ASSISTANT_UI_COPY = {\n title: 'Max',\n subtitle: 'Maxtime Virtual Assistant',\n launcherLabel: 'Open Maxtime virtual assistant',\n openTooltip: 'Open Maxtime virtual assistant',\n closeLabel: 'Close Maxtime virtual assistant',\n placeholder: 'Ask Maxtime virtual assistant',\n typingLabel: 'Maxtime virtual assistant is typing',\n errorMessage: 'Maxtime virtual assistant could not be reached. Please try again.'\n};\n\ntype AssistantBootstrapConfig = Pick<InitialConfig, 'initialMessage'> &\n Required<Pick<InitialConfig, 'initialSuggestions'>>;\n\nconst DEFAULT_ASSISTANT_BOOTSTRAP: AssistantBootstrapConfig = {\n initialMessage: undefined,\n initialSuggestions: []\n};\n\n@Component({\n selector: 'max-assistant',\n imports: [CommonModule, FormsModule, ButtonModule, DrawerModule, TextareaModule, TooltipModule],\n templateUrl: './max-assistant.component.html',\n styleUrl: './max-assistant.component.scss'\n})\nexport class MaxAssistantComponent {\n @ViewChild('messagesViewport') private messagesViewport?: ElementRef<HTMLElement>;\n\n @Input() app?: AssistantProduct;\n @Input() user:\n | Partial<AssistantUser>\n | (() => Partial<AssistantUser>) = {};\n @Input() initialConfig: InitialConfig = {};\n\n protected readonly panelVisible = signal(false);\n protected readonly isSending = signal(false);\n protected readonly input = signal('');\n protected readonly conversationId = signal<string | undefined>(undefined);\n protected readonly messages = signal<AssistantMessage[]>([]);\n protected readonly expandedInferenceMessageIds = signal<ReadonlySet<string>>(new Set<string>());\n\n private readonly assistantService = inject(MaxAssistantService);\n private readonly destroyRef = inject(DestroyRef);\n\n protected openPanel() {\n this.panelVisible.set(true);\n\n if (!this.messages().length && this.bootstrapConfig.initialMessage) {\n this.messages.set([\n this.createMessage(\n 'assistant',\n this.bootstrapConfig.initialMessage,\n this.bootstrapConfig.initialSuggestions\n )\n ]);\n }\n\n this.scrollToLatest();\n }\n\n protected get uiCopy(): typeof ASSISTANT_UI_COPY {\n return ASSISTANT_UI_COPY;\n }\n\n protected get bootstrapConfig(): AssistantBootstrapConfig {\n return {\n ...DEFAULT_ASSISTANT_BOOTSTRAP,\n initialMessage: this.initialConfig.initialMessage,\n initialSuggestions: this.initialConfig.initialSuggestions ?? []\n };\n }\n\n protected closePanel() {\n this.panelVisible.set(false);\n }\n\n protected sendMessage(message = this.input()) {\n const trimmedMessage = message.trim();\n\n if (!trimmedMessage || this.isSending()) {\n return;\n }\n\n this.input.set('');\n this.appendMessage(this.createMessage('user', trimmedMessage));\n this.isSending.set(true);\n\n this.assistantService\n .sendMessage(trimmedMessage, this.conversationId(), this.getAssistantConfig())\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: response => {\n this.conversationId.set(response.conversationId);\n this.appendMessage(this.createAssistantResponseMessage(response, trimmedMessage));\n this.isSending.set(false);\n },\n error: () => {\n this.appendMessage({\n ...this.createMessage('assistant', this.uiCopy.errorMessage),\n isError: true\n });\n this.isSending.set(false);\n }\n });\n }\n\n protected useSuggestion(suggestion: string) {\n this.sendMessage(suggestion);\n }\n\n protected onComposerKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.sendMessage();\n }\n }\n\n protected isInferenceDetailsVisible(messageId: string): boolean {\n return this.expandedInferenceMessageIds().has(messageId);\n }\n\n protected toggleInferenceDetails(messageId: string) {\n const willOpen = !this.isInferenceDetailsVisible(messageId);\n\n this.expandedInferenceMessageIds.update(expandedIds => {\n const nextExpandedIds = new Set(expandedIds);\n\n if (nextExpandedIds.has(messageId)) {\n nextExpandedIds.delete(messageId);\n } else {\n nextExpandedIds.add(messageId);\n }\n\n return nextExpandedIds;\n });\n\n if (willOpen) {\n this.scrollToLatest();\n }\n }\n\n private getAssistantConfig(): MaxAssistantConfig {\n return {\n app: this.app,\n user: this.user\n };\n }\n\n private appendMessage(message: AssistantMessage) {\n this.messages.update(messages => [...messages, message]);\n this.scrollToLatest();\n }\n\n private createAssistantResponseMessage(\n response: AssistantChatResponse,\n userQuery: string\n ): AssistantMessage {\n const displayResponse = this.createDisplayResponse(response, userQuery);\n\n return this.createMessage(\n 'assistant',\n displayResponse.agentInferredResponse || response.answer,\n response.suggestions,\n response.sources,\n response.intent,\n response.intentLabel,\n response.app,\n response.productLabel,\n response.apiModule,\n response.confidence,\n response.parameters ?? response.entities,\n response.apiCalls,\n response.mockResult,\n response.llmUsed,\n response.availableModules,\n displayResponse\n );\n }\n\n private createMessage(\n role: AssistantMessage['role'],\n content: string,\n suggestions: string[] = [],\n sources: AssistantMessage['sources'] = [],\n intent?: string,\n intentLabel?: string,\n app?: string,\n productLabel?: string,\n apiModule?: string,\n confidence?: number,\n parameters?: AssistantFieldMap,\n apiCalls?: AssistantMessage['apiCalls'],\n mockResult?: AssistantFieldMap,\n llmUsed?: boolean,\n availableModules?: string[],\n displayResponse?: AssistantDisplayResponse\n ): AssistantMessage {\n return {\n id: this.createId(),\n role,\n content,\n displayResponse,\n formattedParameters: this.formatJson(displayResponse?.agentExtractedIntent?.parameters),\n formattedApiBody: this.formatJson(displayResponse?.agentExtractedIntent?.api?.body),\n formattedApiResponse: this.formatJson(displayResponse?.apiResponse),\n suggestions,\n sources,\n intent,\n intentLabel,\n app,\n productLabel,\n apiModule,\n confidence,\n parameters,\n entities: parameters,\n apiCalls,\n mockResult,\n llmUsed,\n availableModules,\n createdAt: new Date()\n };\n }\n\n private createDisplayResponse(\n response: AssistantChatResponse,\n userQuery: string\n ): AssistantDisplayResponse {\n const provided = response.displayResponse ?? {};\n const extractedIntent = this.createExtractedIntent(response, provided.agentExtractedIntent);\n\n return {\n userQuery: provided.userQuery || userQuery,\n agentInferredResponse: provided.agentInferredResponse || response.answer,\n agentExtractedIntent: extractedIntent,\n apiResponse: provided.apiResponse ?? this.getApiResponseFallback(response),\n markdown: provided.markdown\n };\n }\n\n private createExtractedIntent(\n response: AssistantChatResponse,\n provided?: AssistantExtractedIntent\n ): AssistantExtractedIntent {\n return {\n project: provided?.project ?? response.productLabel ?? response.app,\n projectKey: provided?.projectKey ?? response.app,\n module: provided?.module ?? response.apiModule,\n intent: provided?.intent ?? response.intent,\n intentLabel: provided?.intentLabel ?? response.intentLabel,\n confidence: provided?.confidence ?? response.confidence,\n parameters: provided?.parameters ?? response.parameters ?? response.entities,\n api: provided?.api ?? response.apiCalls?.[0]\n };\n }\n\n private getApiResponseFallback(response: AssistantChatResponse): AssistantFieldMap | undefined {\n if (!response.mockResult || !Object.keys(response.mockResult).length) {\n return undefined;\n }\n\n return response.mockResult;\n }\n\n private formatJson(value: unknown): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return JSON.stringify(value, null, 2);\n }\n\n private createId(): string {\n return globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random()}`;\n }\n\n private scrollToLatest() {\n setTimeout(() => {\n const element = this.messagesViewport?.nativeElement;\n\n if (element) {\n element.scrollTop = element.scrollHeight;\n }\n });\n }\n}\n","<button\n pButton\n type=\"button\"\n class=\"assistant-launcher\"\n [attr.aria-label]=\"uiCopy.launcherLabel\"\n [pTooltip]=\"uiCopy.openTooltip\"\n tooltipPosition=\"left\"\n (click)=\"openPanel()\"\n>\n <span class=\"mascot\" aria-hidden=\"true\"></span>\n</button>\n\n<p-drawer\n [visible]=\"panelVisible()\"\n (visibleChange)=\"panelVisible.set($event)\"\n position=\"right\"\n styleClass=\"assistant-drawer\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n [showCloseIcon]=\"false\"\n>\n <section class=\"assistant-panel\" [attr.aria-label]=\"uiCopy.title\">\n <header class=\"assistant-header\">\n <span class=\"mascot large\" aria-hidden=\"true\"></span>\n <div>\n <h2>{{ uiCopy.title }}</h2>\n <span>{{ uiCopy.subtitle }}</span>\n </div>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-times\"\n text\n rounded\n severity=\"secondary\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n (click)=\"closePanel()\"\n ></button>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article class=\"message {{ message.role }}\" [class.error]=\"message.isError\">\n @if(message.displayResponse; as responseDetails) {\n <p class=\"assistant-result\">{{ responseDetails.agentInferredResponse || message.content }}</p>\n <button\n type=\"button\"\n class=\"inference-toggle\"\n [attr.aria-expanded]=\"isInferenceDetailsVisible(message.id)\"\n (click)=\"toggleInferenceDetails(message.id)\"\n >\n {{ isInferenceDetailsVisible(message.id) ? 'Hide Details' : 'Show Details' }}\n </button>\n\n @if(isInferenceDetailsVisible(message.id)) {\n <div class=\"response-details\">\n @if(responseDetails.userQuery) {\n <section class=\"response-section\">\n <h3>User Query</h3>\n <p class=\"quoted\">\"{{ responseDetails.userQuery }}\"</p>\n </section>\n }\n\n @if(responseDetails.agentExtractedIntent; as intent) {\n <section class=\"response-section\">\n <h3>Agent Extracted Intent</h3>\n <dl class=\"detail-grid\">\n @if(intent.project || intent.projectKey) {\n <div>\n <dt>Project</dt>\n <dd>\n {{ intent.project || intent.projectKey }}\n @if(intent.projectKey) {\n <span>{{ intent.projectKey }}</span>\n }\n </dd>\n </div>\n }\n @if(intent.module) {\n <div>\n <dt>Module</dt>\n <dd>{{ intent.module }}</dd>\n </div>\n }\n @if(intent.intentLabel) {\n <div>\n <dt>Intent Label</dt>\n <dd>{{ intent.intentLabel }}</dd>\n </div>\n }\n @if(intent.intent) {\n <div>\n <dt>Intent</dt>\n <dd>{{ intent.intent }}</dd>\n </div>\n }\n @if(intent.confidence !== undefined) {\n <div>\n <dt>Confidence</dt>\n <dd>{{ intent.confidence | percent: '1.0-0' }}</dd>\n </div>\n }\n </dl>\n\n @if(message.formattedParameters) {\n <div class=\"json-block\">\n <strong>Parameters</strong>\n <pre>{{ message.formattedParameters }}</pre>\n </div>\n }\n\n @if(intent.api?.url || intent.api?.method) {\n <div class=\"api-call-summary\">\n <strong>API Called</strong>\n <code>{{ intent.api?.method || 'GET' }} {{ intent.api?.url || 'URL not provided' }}</code>\n </div>\n }\n\n @if(message.formattedApiBody) {\n <div class=\"json-block\">\n <strong>API Body</strong>\n <pre>{{ message.formattedApiBody }}</pre>\n </div>\n }\n </section>\n }\n\n @if(message.formattedApiResponse) {\n <section class=\"response-section\">\n <h3>API Response</h3>\n <div class=\"json-block\">\n <strong>JSON</strong>\n <pre>{{ message.formattedApiResponse }}</pre>\n </div>\n </section>\n }\n </div>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestion\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n </article>\n }\n @if(isSending()) {\n <article class=\"message assistant typing\" [attr.aria-label]=\"uiCopy.typingLabel\">\n <span></span>\n <span></span>\n <span></span>\n </article>\n }\n </div>\n\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n pTextarea\n name=\"assistantPrompt\"\n rows=\"2\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </section>\n</p-drawer>\n","/*\n * Public API Surface of max-agent-ui\n */\n\nexport * from './lib/components/assistant/max-assistant.component';\nexport * from './lib/config/assistant.config';\nexport * from './lib/models/assistant.models';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"max-agent-ui.mjs","sources":["../../../projects/max-agent-ui/src/lib/config/assistant-bootstrap.config.ts","../../../projects/max-agent-ui/src/lib/config/assistant.config.ts","../../../projects/max-agent-ui/src/lib/components/assistant/max-assistant.service.ts","../../../projects/max-agent-ui/src/lib/components/assistant/max-assistant.component.ts","../../../projects/max-agent-ui/src/lib/components/assistant/max-assistant.component.html","../../../projects/max-agent-ui/src/public-api.ts","../../../projects/max-agent-ui/src/max-agent-ui.ts"],"sourcesContent":["import { AssistantProduct } from '../models/assistant.models';\n\nexport interface AssistantBootstrapConfig {\n initialMessage?: string;\n initialSuggestions: string[];\n}\n\nconst DEFAULT_ASSISTANT_BOOTSTRAP: AssistantBootstrapConfig = {\n initialMessage: undefined,\n initialSuggestions: []\n};\n\nconst ASSISTANT_BOOTSTRAP_BY_APP: Record<string, AssistantBootstrapConfig> = {\n cortex: {\n initialMessage: 'Hi, I am Max, the Maxtime Virtual Assistant. How can I help you today?',\n initialSuggestions: ['Show my timetable', 'Open scheduling', 'View reports']\n },\n nemesys: {\n initialMessage: 'Hi, I am Max, the Maxtime Virtual Assistant. How can I help you today?',\n initialSuggestions: ['Show scheduling plans', 'Check resource availability', 'Find conflicts']\n },\n attendance: {\n initialMessage: 'Hi, I am Max, the Maxtime Virtual Assistant. How can I help you today?',\n initialSuggestions: ['Show attendance summary', 'Find missing attendance', 'View reports']\n }\n};\n\nexport function getAssistantBootstrapConfig(app?: AssistantProduct): AssistantBootstrapConfig {\n const appKey = app?.trim().toLowerCase();\n\n if (!appKey) {\n return DEFAULT_ASSISTANT_BOOTSTRAP;\n }\n\n return ASSISTANT_BOOTSTRAP_BY_APP[appKey] ?? DEFAULT_ASSISTANT_BOOTSTRAP;\n}\n","import { InjectionToken } from '@angular/core';\n\nimport { AssistantProduct, AssistantUser } from '../models/assistant.models';\n\nexport interface MaxAssistantConfig {\n assistantApiUrl?: string;\n app?: AssistantProduct;\n user?: Partial<AssistantUser> | (() => Partial<AssistantUser>);\n}\n\nexport const MAX_ASSISTANT_CONFIG = new InjectionToken<MaxAssistantConfig>(\n 'MAX_ASSISTANT_CONFIG',\n {\n factory: () => ({})\n }\n);\n","import { HttpClient } from '@angular/common/http';\nimport { inject, Injectable } from '@angular/core';\nimport { Observable, throwError } from 'rxjs';\n\nimport { MAX_ASSISTANT_CONFIG, MaxAssistantConfig } from '../../config/assistant.config';\nimport {\n AssistantChatRequest,\n AssistantChatResponse,\n AssistantProduct,\n AssistantUser\n} from '../../models/assistant.models';\n\nconst DEFAULT_ASSISTANT_CHAT_URL =\n 'https://fhmaof3b4kaxqfbnomfstxyhw40rrcjr.lambda-url.eu-west-2.on.aws/chat';\nconst DEFAULT_APP = 'assistant';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class MaxAssistantService {\n private readonly config = inject(MAX_ASSISTANT_CONFIG);\n private readonly http = inject(HttpClient, { optional: true });\n\n sendMessage(\n message: string,\n conversationId?: string,\n config: MaxAssistantConfig = {}\n ): Observable<AssistantChatResponse> {\n const assistantConfig = {\n ...this.config,\n ...config\n };\n const request: AssistantChatRequest = {\n message,\n conversationId,\n app: this.getApp(assistantConfig),\n user: this.getUser(assistantConfig)\n };\n\n return this.postMessage(request, assistantConfig);\n }\n\n private postMessage(\n request: AssistantChatRequest,\n config: MaxAssistantConfig\n ): Observable<AssistantChatResponse> {\n if (!this.http) {\n return throwError(\n () => new Error('HttpClient is not available. Add provideHttpClient() to the host app.')\n );\n }\n\n return this.http.post<AssistantChatResponse>(this.getChatUrl(config), request);\n }\n\n private getChatUrl(config: MaxAssistantConfig): string {\n return config.assistantApiUrl?.trim() || DEFAULT_ASSISTANT_CHAT_URL;\n }\n\n private getApp(config: MaxAssistantConfig): AssistantProduct {\n return config.app || DEFAULT_APP;\n }\n\n private getUser(config: MaxAssistantConfig): AssistantUser {\n if (typeof config.user === 'function') {\n return config.user();\n }\n\n return config.user ?? {};\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, DestroyRef, ElementRef, inject, Input, signal, ViewChild } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\nimport { ButtonModule } from 'primeng/button';\nimport { DrawerModule } from 'primeng/drawer';\nimport { TextareaModule } from 'primeng/textarea';\nimport { TooltipModule } from 'primeng/tooltip';\n\nimport {\n AssistantBootstrapConfig,\n getAssistantBootstrapConfig\n} from '../../config/assistant-bootstrap.config';\nimport { MaxAssistantConfig } from '../../config/assistant.config';\nimport {\n AssistantChatResponse,\n AssistantDisplayResponse,\n AssistantExtractedIntent,\n AssistantFieldMap,\n AssistantMessage,\n AssistantProduct,\n AssistantUser\n} from '../../models/assistant.models';\nimport { MaxAssistantService } from './max-assistant.service';\n\nconst ASSISTANT_UI_COPY = {\n title: 'Max',\n subtitle: 'Maxtime Virtual Assistant',\n launcherLabel: 'Open Maxtime virtual assistant',\n openTooltip: 'Open Maxtime virtual assistant',\n closeLabel: 'Close Maxtime virtual assistant',\n placeholder: 'Ask Maxtime virtual assistant',\n typingLabel: 'Maxtime virtual assistant is typing',\n errorMessage: 'Maxtime virtual assistant could not be reached. Please try again.'\n};\n\n@Component({\n selector: 'max-assistant',\n imports: [CommonModule, FormsModule, ButtonModule, DrawerModule, TextareaModule, TooltipModule],\n templateUrl: './max-assistant.component.html',\n styleUrl: './max-assistant.component.scss'\n})\nexport class MaxAssistantComponent {\n @ViewChild('messagesViewport') private messagesViewport?: ElementRef<HTMLElement>;\n\n @Input() app?: AssistantProduct;\n @Input() user:\n | Partial<AssistantUser>\n | (() => Partial<AssistantUser>) = {};\n\n protected readonly panelVisible = signal(false);\n protected readonly isSending = signal(false);\n protected readonly input = signal('');\n protected readonly conversationId = signal<string | undefined>(undefined);\n protected readonly messages = signal<AssistantMessage[]>([]);\n protected readonly expandedInferenceMessageIds = signal<ReadonlySet<string>>(new Set<string>());\n\n private readonly assistantService = inject(MaxAssistantService);\n private readonly destroyRef = inject(DestroyRef);\n\n protected openPanel() {\n this.panelVisible.set(true);\n\n if (!this.messages().length && this.bootstrapConfig.initialMessage) {\n this.messages.set([\n this.createMessage(\n 'assistant',\n this.bootstrapConfig.initialMessage,\n this.bootstrapConfig.initialSuggestions\n )\n ]);\n }\n\n this.scrollToLatest();\n }\n\n protected get uiCopy(): typeof ASSISTANT_UI_COPY {\n return ASSISTANT_UI_COPY;\n }\n\n protected get bootstrapConfig(): AssistantBootstrapConfig {\n return getAssistantBootstrapConfig(this.app);\n }\n\n protected closePanel() {\n this.panelVisible.set(false);\n }\n\n protected sendMessage(message = this.input()) {\n const trimmedMessage = message.trim();\n\n if (!trimmedMessage || this.isSending()) {\n return;\n }\n\n this.input.set('');\n this.appendMessage(this.createMessage('user', trimmedMessage));\n this.isSending.set(true);\n\n this.assistantService\n .sendMessage(trimmedMessage, this.conversationId(), this.getAssistantConfig())\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe({\n next: response => {\n this.conversationId.set(response.conversationId);\n this.appendMessage(this.createAssistantResponseMessage(response, trimmedMessage));\n this.isSending.set(false);\n },\n error: () => {\n this.appendMessage({\n ...this.createMessage('assistant', this.uiCopy.errorMessage),\n isError: true\n });\n this.isSending.set(false);\n }\n });\n }\n\n protected useSuggestion(suggestion: string) {\n this.sendMessage(suggestion);\n }\n\n protected onComposerKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.sendMessage();\n }\n }\n\n protected isInferenceDetailsVisible(messageId: string): boolean {\n return this.expandedInferenceMessageIds().has(messageId);\n }\n\n protected toggleInferenceDetails(messageId: string) {\n const willOpen = !this.isInferenceDetailsVisible(messageId);\n\n this.expandedInferenceMessageIds.update(expandedIds => {\n const nextExpandedIds = new Set(expandedIds);\n\n if (nextExpandedIds.has(messageId)) {\n nextExpandedIds.delete(messageId);\n } else {\n nextExpandedIds.add(messageId);\n }\n\n return nextExpandedIds;\n });\n\n if (willOpen) {\n this.scrollToLatest();\n }\n }\n\n private getAssistantConfig(): MaxAssistantConfig {\n return {\n app: this.app,\n user: this.user\n };\n }\n\n private appendMessage(message: AssistantMessage) {\n this.messages.update(messages => [...messages, message]);\n this.scrollToLatest();\n }\n\n private createAssistantResponseMessage(\n response: AssistantChatResponse,\n userQuery: string\n ): AssistantMessage {\n const displayResponse = this.createDisplayResponse(response, userQuery);\n\n return this.createMessage(\n 'assistant',\n displayResponse.agentInferredResponse || response.answer,\n response.suggestions,\n response.sources,\n response.intent,\n response.intentLabel,\n response.app,\n response.productLabel,\n response.apiModule,\n response.confidence,\n response.parameters ?? response.entities,\n response.apiCalls,\n response.mockResult,\n response.llmUsed,\n response.availableModules,\n displayResponse\n );\n }\n\n private createMessage(\n role: AssistantMessage['role'],\n content: string,\n suggestions: string[] = [],\n sources: AssistantMessage['sources'] = [],\n intent?: string,\n intentLabel?: string,\n app?: string,\n productLabel?: string,\n apiModule?: string,\n confidence?: number,\n parameters?: AssistantFieldMap,\n apiCalls?: AssistantMessage['apiCalls'],\n mockResult?: AssistantFieldMap,\n llmUsed?: boolean,\n availableModules?: string[],\n displayResponse?: AssistantDisplayResponse\n ): AssistantMessage {\n return {\n id: this.createId(),\n role,\n content,\n displayResponse,\n formattedParameters: this.formatJson(displayResponse?.agentExtractedIntent?.parameters),\n formattedApiBody: this.formatJson(displayResponse?.agentExtractedIntent?.api?.body),\n formattedApiResponse: this.formatJson(displayResponse?.apiResponse),\n suggestions,\n sources,\n intent,\n intentLabel,\n app,\n productLabel,\n apiModule,\n confidence,\n parameters,\n entities: parameters,\n apiCalls,\n mockResult,\n llmUsed,\n availableModules,\n createdAt: new Date()\n };\n }\n\n private createDisplayResponse(\n response: AssistantChatResponse,\n userQuery: string\n ): AssistantDisplayResponse {\n const provided = response.displayResponse ?? {};\n const extractedIntent = this.createExtractedIntent(response, provided.agentExtractedIntent);\n\n return {\n userQuery: provided.userQuery || userQuery,\n agentInferredResponse: provided.agentInferredResponse || response.answer,\n agentExtractedIntent: extractedIntent,\n apiResponse: provided.apiResponse ?? this.getApiResponseFallback(response),\n markdown: provided.markdown\n };\n }\n\n private createExtractedIntent(\n response: AssistantChatResponse,\n provided?: AssistantExtractedIntent\n ): AssistantExtractedIntent {\n return {\n project: provided?.project ?? response.productLabel ?? response.app,\n projectKey: provided?.projectKey ?? response.app,\n module: provided?.module ?? response.apiModule,\n intent: provided?.intent ?? response.intent,\n intentLabel: provided?.intentLabel ?? response.intentLabel,\n confidence: provided?.confidence ?? response.confidence,\n parameters: provided?.parameters ?? response.parameters ?? response.entities,\n api: provided?.api ?? response.apiCalls?.[0]\n };\n }\n\n private getApiResponseFallback(response: AssistantChatResponse): AssistantFieldMap | undefined {\n if (!response.mockResult || !Object.keys(response.mockResult).length) {\n return undefined;\n }\n\n return response.mockResult;\n }\n\n private formatJson(value: unknown): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return JSON.stringify(value, null, 2);\n }\n\n private createId(): string {\n return globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random()}`;\n }\n\n private scrollToLatest() {\n setTimeout(() => {\n const element = this.messagesViewport?.nativeElement;\n\n if (element) {\n element.scrollTop = element.scrollHeight;\n }\n });\n }\n}\n","<button\n pButton\n type=\"button\"\n class=\"assistant-launcher\"\n [attr.aria-label]=\"uiCopy.launcherLabel\"\n [pTooltip]=\"uiCopy.openTooltip\"\n tooltipPosition=\"left\"\n (click)=\"openPanel()\"\n>\n <span class=\"mascot\" aria-hidden=\"true\"></span>\n</button>\n\n<p-drawer\n [visible]=\"panelVisible()\"\n (visibleChange)=\"panelVisible.set($event)\"\n position=\"right\"\n styleClass=\"assistant-drawer\"\n [modal]=\"false\"\n [blockScroll]=\"false\"\n [showCloseIcon]=\"false\"\n>\n <section class=\"assistant-panel\" [attr.aria-label]=\"uiCopy.title\">\n <header class=\"assistant-header\">\n <span class=\"mascot large\" aria-hidden=\"true\"></span>\n <div>\n <h2>{{ uiCopy.title }}</h2>\n <span>{{ uiCopy.subtitle }}</span>\n </div>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-times\"\n text\n rounded\n severity=\"secondary\"\n [attr.aria-label]=\"uiCopy.closeLabel\"\n (click)=\"closePanel()\"\n ></button>\n </header>\n\n <div #messagesViewport class=\"assistant-messages\">\n @for(message of messages(); track message.id) {\n <article class=\"message {{ message.role }}\" [class.error]=\"message.isError\">\n @if(message.displayResponse; as responseDetails) {\n <p class=\"assistant-result\">{{ responseDetails.agentInferredResponse || message.content }}</p>\n <button\n type=\"button\"\n class=\"inference-toggle\"\n [attr.aria-expanded]=\"isInferenceDetailsVisible(message.id)\"\n (click)=\"toggleInferenceDetails(message.id)\"\n >\n {{ isInferenceDetailsVisible(message.id) ? 'Hide Details' : 'Show Details' }}\n </button>\n\n @if(isInferenceDetailsVisible(message.id)) {\n <div class=\"response-details\">\n @if(responseDetails.userQuery) {\n <section class=\"response-section\">\n <h3>User Query</h3>\n <p class=\"quoted\">\"{{ responseDetails.userQuery }}\"</p>\n </section>\n }\n\n @if(responseDetails.agentExtractedIntent; as intent) {\n <section class=\"response-section\">\n <h3>Agent Extracted Intent</h3>\n <dl class=\"detail-grid\">\n @if(intent.project || intent.projectKey) {\n <div>\n <dt>Project</dt>\n <dd>\n {{ intent.project || intent.projectKey }}\n @if(intent.projectKey) {\n <span>{{ intent.projectKey }}</span>\n }\n </dd>\n </div>\n }\n @if(intent.module) {\n <div>\n <dt>Module</dt>\n <dd>{{ intent.module }}</dd>\n </div>\n }\n @if(intent.intentLabel) {\n <div>\n <dt>Intent Label</dt>\n <dd>{{ intent.intentLabel }}</dd>\n </div>\n }\n @if(intent.intent) {\n <div>\n <dt>Intent</dt>\n <dd>{{ intent.intent }}</dd>\n </div>\n }\n @if(intent.confidence !== undefined) {\n <div>\n <dt>Confidence</dt>\n <dd>{{ intent.confidence | percent: '1.0-0' }}</dd>\n </div>\n }\n </dl>\n\n @if(message.formattedParameters) {\n <div class=\"json-block\">\n <strong>Parameters</strong>\n <pre>{{ message.formattedParameters }}</pre>\n </div>\n }\n\n @if(intent.api?.url || intent.api?.method) {\n <div class=\"api-call-summary\">\n <strong>API Called</strong>\n <code>{{ intent.api?.method || 'GET' }} {{ intent.api?.url || 'URL not provided' }}</code>\n </div>\n }\n\n @if(message.formattedApiBody) {\n <div class=\"json-block\">\n <strong>API Body</strong>\n <pre>{{ message.formattedApiBody }}</pre>\n </div>\n }\n </section>\n }\n\n @if(message.formattedApiResponse) {\n <section class=\"response-section\">\n <h3>API Response</h3>\n <div class=\"json-block\">\n <strong>JSON</strong>\n <pre>{{ message.formattedApiResponse }}</pre>\n </div>\n </section>\n }\n </div>\n }\n } @else {\n <p>{{ message.content }}</p>\n }\n @if(message.role === 'assistant' && message.suggestions?.length) {\n <div class=\"suggestions\">\n @for(suggestion of message.suggestions ?? []; track suggestion) {\n <button\n pButton\n type=\"button\"\n size=\"small\"\n text\n severity=\"secondary\"\n class=\"suggestion-chip\"\n [label]=\"suggestion\"\n (click)=\"useSuggestion(suggestion)\"\n ></button>\n }\n </div>\n }\n </article>\n }\n @if(isSending()) {\n <article class=\"message assistant typing\" [attr.aria-label]=\"uiCopy.typingLabel\">\n <span></span>\n <span></span>\n <span></span>\n </article>\n }\n </div>\n\n <form class=\"assistant-composer\" (ngSubmit)=\"sendMessage()\">\n <textarea\n pTextarea\n name=\"assistantPrompt\"\n rows=\"2\"\n [placeholder]=\"uiCopy.placeholder\"\n [ngModel]=\"input()\"\n (ngModelChange)=\"input.set($event)\"\n (keydown)=\"onComposerKeydown($event)\"\n >\n </textarea>\n <button\n pButton\n type=\"submit\"\n icon=\"pi pi-send\"\n aria-label=\"Send message\"\n [disabled]=\"!input().trim() || isSending()\"\n ></button>\n </form>\n </section>\n</p-drawer>\n","/*\n * Public API Surface of max-agent-ui\n */\n\nexport * from './lib/components/assistant/max-assistant.component';\nexport * from './lib/config/assistant.config';\nexport * from './lib/models/assistant.models';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/types/max-agent-ui.d.ts
CHANGED
|
@@ -46,10 +46,6 @@ interface AssistantChatRequest {
|
|
|
46
46
|
app: AssistantProduct;
|
|
47
47
|
user: AssistantUser;
|
|
48
48
|
}
|
|
49
|
-
interface InitialConfig {
|
|
50
|
-
initialMessage?: string;
|
|
51
|
-
initialSuggestions?: string[];
|
|
52
|
-
}
|
|
53
49
|
interface AssistantChatResponse {
|
|
54
50
|
answer: string;
|
|
55
51
|
conversationId: string;
|
|
@@ -96,6 +92,11 @@ interface AssistantMessage {
|
|
|
96
92
|
isError?: boolean;
|
|
97
93
|
}
|
|
98
94
|
|
|
95
|
+
interface AssistantBootstrapConfig {
|
|
96
|
+
initialMessage?: string;
|
|
97
|
+
initialSuggestions: string[];
|
|
98
|
+
}
|
|
99
|
+
|
|
99
100
|
declare const ASSISTANT_UI_COPY: {
|
|
100
101
|
title: string;
|
|
101
102
|
subtitle: string;
|
|
@@ -106,12 +107,10 @@ declare const ASSISTANT_UI_COPY: {
|
|
|
106
107
|
typingLabel: string;
|
|
107
108
|
errorMessage: string;
|
|
108
109
|
};
|
|
109
|
-
type AssistantBootstrapConfig = Pick<InitialConfig, 'initialMessage'> & Required<Pick<InitialConfig, 'initialSuggestions'>>;
|
|
110
110
|
declare class MaxAssistantComponent {
|
|
111
111
|
private messagesViewport?;
|
|
112
112
|
app?: AssistantProduct;
|
|
113
113
|
user: Partial<AssistantUser> | (() => Partial<AssistantUser>);
|
|
114
|
-
initialConfig: InitialConfig;
|
|
115
114
|
protected readonly panelVisible: _angular_core.WritableSignal<boolean>;
|
|
116
115
|
protected readonly isSending: _angular_core.WritableSignal<boolean>;
|
|
117
116
|
protected readonly input: _angular_core.WritableSignal<string>;
|
|
@@ -140,7 +139,7 @@ declare class MaxAssistantComponent {
|
|
|
140
139
|
private createId;
|
|
141
140
|
private scrollToLatest;
|
|
142
141
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MaxAssistantComponent, never>;
|
|
143
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MaxAssistantComponent, "max-assistant", never, { "app": { "alias": "app"; "required": false; }; "user": { "alias": "user"; "required": false; };
|
|
142
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MaxAssistantComponent, "max-assistant", never, { "app": { "alias": "app"; "required": false; }; "user": { "alias": "user"; "required": false; }; }, {}, never, never, true, never>;
|
|
144
143
|
}
|
|
145
144
|
|
|
146
145
|
interface MaxAssistantConfig {
|
|
@@ -151,4 +150,4 @@ interface MaxAssistantConfig {
|
|
|
151
150
|
declare const MAX_ASSISTANT_CONFIG: InjectionToken<MaxAssistantConfig>;
|
|
152
151
|
|
|
153
152
|
export { MAX_ASSISTANT_CONFIG, MaxAssistantComponent };
|
|
154
|
-
export type { AssistantApiCall, AssistantChatRequest, AssistantChatResponse, AssistantDisplayResponse, AssistantExtractedIntent, AssistantFieldMap, AssistantFieldValue, AssistantMessage, AssistantProduct, AssistantSource, AssistantUser,
|
|
153
|
+
export type { AssistantApiCall, AssistantChatRequest, AssistantChatResponse, AssistantDisplayResponse, AssistantExtractedIntent, AssistantFieldMap, AssistantFieldValue, AssistantMessage, AssistantProduct, AssistantSource, AssistantUser, MaxAssistantConfig };
|