@c8y/ngx-components 1023.0.2 → 1023.4.5
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/ai/agent-chat/index.d.ts +114 -0
- package/ai/agent-chat/index.d.ts.map +1 -0
- package/ai/ai-chat/index.d.ts +145 -0
- package/ai/ai-chat/index.d.ts.map +1 -0
- package/ai/index.d.ts +203 -0
- package/ai/index.d.ts.map +1 -0
- package/context-dashboard/device/add/index.d.ts +15 -1
- package/context-dashboard/device/add/index.d.ts.map +1 -1
- package/context-dashboard/device/view/index.d.ts +14 -2
- package/context-dashboard/device/view/index.d.ts.map +1 -1
- package/context-dashboard/devicemanagement/index.d.ts +10 -0
- package/context-dashboard/devicemanagement/index.d.ts.map +1 -0
- package/context-dashboard/index.d.ts +6 -30
- package/context-dashboard/index.d.ts.map +1 -1
- package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs +387 -0
- package/fesm2022/c8y-ngx-components-ai-agent-chat.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs +258 -0
- package/fesm2022/c8y-ngx-components-ai-ai-chat.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-ai.mjs +291 -0
- package/fesm2022/c8y-ngx-components-ai.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-context-dashboard-cockpit-home-dashboard.mjs +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard-cockpit-home-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard-device-add.mjs +1 -1
- package/fesm2022/c8y-ngx-components-context-dashboard-device-view.mjs +2 -2
- package/fesm2022/c8y-ngx-components-context-dashboard-devicemanagement.mjs +68 -0
- package/fesm2022/c8y-ngx-components-context-dashboard-devicemanagement.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs +33 -46
- package/fesm2022/c8y-ngx-components-context-dashboard.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-global-context.mjs +10 -10
- package/fesm2022/c8y-ngx-components-global-context.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-register-device.mjs +4 -6
- package/fesm2022/c8y-ngx-components-register-device.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-sensor-phone-sensor-phone-modal.mjs +2 -2
- package/fesm2022/c8y-ngx-components-sensor-phone-sensor-phone-modal.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs +574 -0
- package/fesm2022/c8y-ngx-components-widgets-definitions-html-widget-ai-config.mjs.map +1 -0
- package/fesm2022/c8y-ngx-components-widgets-exports.mjs +8 -1
- package/fesm2022/c8y-ngx-components-widgets-exports.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components-widgets-implementations-html-widget.mjs +176 -41
- package/fesm2022/c8y-ngx-components-widgets-implementations-html-widget.mjs.map +1 -1
- package/fesm2022/c8y-ngx-components.mjs +98 -46
- package/fesm2022/c8y-ngx-components.mjs.map +1 -1
- package/index.d.ts +25 -4
- package/index.d.ts.map +1 -1
- package/locales/de.po +150 -15
- package/locales/es.po +150 -15
- package/locales/fr.po +149 -15
- package/locales/ja_JP.po +147 -12
- package/locales/ko.po +149 -15
- package/locales/locales.pot +144 -9
- package/locales/nl.po +150 -15
- package/locales/pl.po +149 -14
- package/locales/pt_BR.po +149 -15
- package/locales/zh_CN.po +149 -14
- package/locales/zh_TW.po +148 -13
- package/package.json +1 -1
- package/register-device/index.d.ts.map +1 -1
- package/widgets/cockpit-exports/index.d.ts +6 -0
- package/widgets/cockpit-exports/index.d.ts.map +1 -1
- package/widgets/definitions/html-widget-ai-config/index.d.ts +6 -0
- package/widgets/definitions/html-widget-ai-config/index.d.ts.map +1 -0
- package/widgets/device-management-exports/index.d.ts +6 -0
- package/widgets/device-management-exports/index.d.ts.map +1 -1
- package/widgets/exports/index.d.ts +8 -1
- package/widgets/exports/index.d.ts.map +1 -1
- package/widgets/implementations/html-widget/index.d.ts +72 -16
- package/widgets/implementations/html-widget/index.d.ts.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sources":["../../context-dashboard/add-dashboard.component.ts","../../context-dashboard/add-dashboard.factory.ts","../../context-dashboard/context-dashboard.model.ts","../../context-dashboard/context-dashboard.service.ts","../../context-dashboard/dashboard-detail.service.ts","../../context-dashboard/dashboard-detail.component.ts","../../context-dashboard/memento/dashboard-originator.service.ts","../../context-dashboard/memento/dashboard-caretaker.service.ts","../../context-dashboard/memento/dashboard-edit-mode.service.ts","../../context-dashboard/widget.service.ts","../../context-dashboard/context-dashboard.component.ts","../../context-dashboard/widget-config/appearance-settings.component.ts","../../context-dashboard/type-dashboard-info/type-dashboard-info.component.ts","../../context-dashboard/widget-config-hook/widget-config-hook.model.ts","../../context-dashboard/widget-config-hook/widget-config-hook.service.ts","../../context-dashboard/widget-config.service.ts","../../context-dashboard/widget-config/widget-config-root.component.ts","../../context-dashboard/widget-config.component.ts","../../context-dashboard/widget-config/widget-preview.component.ts","../../context-dashboard/widget-config/widget-config-section.component.ts","../../context-dashboard/widget-config/widget-preview-wrapper.component.ts","../../context-dashboard/paste-dashboard-action.component.ts","../../context-dashboard/context-dashboard.module.ts","../../context-dashboard/dashboard-action-bar.factory.ts","../../context-dashboard/device-info-dashboard/device-info-dashboard.component.ts","../../context-dashboard/device-info-dashboard/device-info-dashboard.module.ts","../../context-dashboard/device-management-home-dashboard/device-management-home-dashboard.component.ts","../../context-dashboard/device-management-home-dashboard/device-management-home-dashboard.module.ts","../../context-dashboard/widget-config/widget-config-appearance.component.ts","../../context-dashboard/widget-config/widget-config-general.component.ts","../../context-dashboard/widget-config/widget-asset-selector.component.ts","../../context-dashboard/new-dashboard.guard.ts","../../context-dashboard/widget-config/global-context-section.component.ts","../../context-dashboard/widget-config/widget-config-feedback.component.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA;AAQI;AACA;AADQ;;;;AAoBX;;ACpBD;AACE;;;;AAMM;;AAoCP;;ACzCD;AACA;;;;;;;;;;;;;;;;AAiBE;;AAEG;AACH;AACD
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../../context-dashboard/add-dashboard.component.ts","../../context-dashboard/add-dashboard.factory.ts","../../context-dashboard/context-dashboard.model.ts","../../context-dashboard/context-dashboard.service.ts","../../context-dashboard/dashboard-detail.service.ts","../../context-dashboard/dashboard-detail.component.ts","../../context-dashboard/memento/dashboard-originator.service.ts","../../context-dashboard/memento/dashboard-caretaker.service.ts","../../context-dashboard/memento/dashboard-edit-mode.service.ts","../../context-dashboard/widget.service.ts","../../context-dashboard/context-dashboard.component.ts","../../context-dashboard/widget-config/appearance-settings.component.ts","../../context-dashboard/type-dashboard-info/type-dashboard-info.component.ts","../../context-dashboard/widget-config-hook/widget-config-hook.model.ts","../../context-dashboard/widget-config-hook/widget-config-hook.service.ts","../../context-dashboard/widget-config.service.ts","../../context-dashboard/widget-config/widget-config-root.component.ts","../../context-dashboard/widget-config.component.ts","../../context-dashboard/widget-config/widget-preview.component.ts","../../context-dashboard/widget-config/widget-config-section.component.ts","../../context-dashboard/widget-config/widget-preview-wrapper.component.ts","../../context-dashboard/paste-dashboard-action.component.ts","../../context-dashboard/context-dashboard.module.ts","../../context-dashboard/dashboard-action-bar.factory.ts","../../context-dashboard/device-info-dashboard/device-info-dashboard.component.ts","../../context-dashboard/device-info-dashboard/device-info-dashboard.module.ts","../../context-dashboard/device-management-home-dashboard/device-management-home-dashboard.component.ts","../../context-dashboard/device-management-home-dashboard/device-management-home-dashboard.module.ts","../../context-dashboard/widget-config/widget-config-appearance.component.ts","../../context-dashboard/widget-config/widget-config-general.component.ts","../../context-dashboard/widget-config/widget-asset-selector.component.ts","../../context-dashboard/new-dashboard.guard.ts","../../context-dashboard/widget-config/global-context-section.component.ts","../../context-dashboard/widget-config/widget-config-feedback.component.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAKA;AAQI;AACA;AADQ;;;;AAoBX;;ACpBD;AACE;;;;AAMM;;AAoCP;;ACzCD;AACA;;;;;;;;;;;;;;;;AAiBE;;AAEG;AACH;AACD;;AAGC;;;AAGG;;AAGH;;AAEG;;AAGH;;AAEG;AACH;AACE;;AAEG;AACH;;AAEF;;;AAGG;AACH;AACE;;AAEA;;AAEF;;;;;AAKG;AACH;AACA;;;;;;AAMG;AACH;AAEA;;AAEG;AACH;AACD;AAEK;;;AAGJ;AACD;;AAGC;AACA;AACA;AACA;AACA;AACA;AACA;AAAY;AAAwB;AACpC;AAAkB;AAAwB;AAC1C;AACA;AACA;AACA;AACA;;;AAGG;AACH;AACA;AACE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AAAmB;;AACpB;AACD;;AAEG;;AAED;;AAEG;;AAEH;;AAEG;AACH;AACA;;AAEG;AACH;AACA;;;;;;;;AAQG;AACH;AACE;AACA;AACA;AACA;AACD;AACD;;AAEG;;AAEJ;AAED;;;;;;;AAOA;;;AAGG;AACG;AACJ;;AAEG;;AAEH;;AAEG;AACH;AACA;;;;;;;;;;;;;AAaG;;AAKG;AACD;;AAKP;AACE;AACA;AACA;AACA;AACA;AACD;AAED;AACE;AACA;AACA;AACD;AAEK;;AAE0D;;;;;AAO/D;AAED;;;;;;;;;;;;;;;;;AAuBA;;;;;;;;;;;;;;;;;;;;;AA4BA;;;;;;;;;;;;;;;;;AA2BA;;;;;AAUC;;;AAIC;AACD;AAED;AACM;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCE;AACD;AAED;AAEM;AAEN;AACA;;;;;;;;;;;;AAaC;;AC3UD;AAwCI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAlDF;AACA;;;;;AAKA;;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;AASA;AAGA;AAIA;;;;AAmEM;AAyBA;AAqCN;AAuBA;;;AAqEM;AAiCN;;;;;AAKG;;AAKH;;;;AAIG;AACH;AASA;AAQA;AAQA;;;AA8BA;;AAaA;AAUA;;AAgDA;;;;;;;;;;;;AAYG;AACH;AAOA;;;;;;;;AAQG;;AA2DH;AAOA;AAWA;AAYM;;;;;;;;;;;;;;;;AAgEN;;;;;;;;;;AAUG;AACH;AA6CA;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACH;AAUA;;AAEG;AACH;;AA4DA;AA4CA;AAQA;AAWA;AAWA;AAuCA;AAeA;AAQA;;;;AAIG;;AAyBH;AAIA;AAiBA;AAWA;AAOA;AAUA;AAUA;;;AAUD;;AC9/BD;AAkCI;AACA;AACA;;;;AA/BF;AACA;;;;;;;;;;;;;;;;AAEC;AACD;;;;;;;;;;;;;;;;;;;;AAEC;AACD;;;;;;;;AAEC;;;;AAKC;AAEF;AAEA;;;;;;;AAuCA;;;;;;AAMG;AACH;;AAoBA;;;;;;AAMG;AACH;AAWA;;;;;;AAMG;AACH;AAoCA;;;;AAIG;AACH;AAaA;;;AAKD;;AC1JD;AA+BI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AApCF;;;;;;;;;AASS;;;;;;;;AAQC;AACA;;;;;AAoCV;AAKA;;;AAqDA;;AAmCM;;;AAqCA;AAeN;AAOA;;;;;;;AAqJA;AAQA;;AA6BA;;AAqCA;;;AAmBD;;AClfD;;AAEG;AACH;AAIE;;AAEG;;AAIH;;;AAGG;;AAEH;;;AAGG;AACH;AAGA;;;AAGG;AACH;AAGA;;AAEG;AACH;;;AAGD;;ACtCD;;AAEG;AACH;AA2Bc;AAvBZ;;AAEG;;AAIH;;AAEG;;AAIH;;;AAGG;;AAEH;;;AAGG;;AAGiB;AACpB;;AAEG;AACH;AAIA;;;AAGG;;AAWH;;;AAGG;;AAWH;;;AAGG;;;;AAQJ;;AC7ED;;;AAGG;AACH;AAqBI;AACA;;AAfF;;AAEG;;AAIH;;AAEG;;AAMO;AAGV;;;AAGG;;AAIH;;;AAGG;;AAKH;;AAEG;AACH;AAGA;;;AAGG;AACH;AAGA;;;AAGG;AACH;AAGA;;;AAGG;AACH;;;AAGD;;ACpED;AAOI;AACA;;;;AAUI;;;AAyCN;;;AASD;;ACRD;;;;AAIG;AACH;AAuFI;AACA;AACA;AACA;AACA;AACyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;;AACoE;;AAC7D;;AA5ET;;AAIA;;AAKA;AAEA;AAEA;;AAIA;;;;;AAKA;;AAEG;AAEH;;AAGA;AAGA;;;;;;;;;;;AAmBA;;;;;;;AAwBsE;;;;;AA+BtE;;;AAGG;;AAOH;;AAEG;AACH;AAUA;;;;;AAKG;AACG;AAYN;;AAEG;;AA2BH;;;;;AAKG;AACH;;AAwCA;;;;;;AAMG;;AAmBH;;AAEG;;;AA0BH;;AAEG;;;AAcH;;;AAGG;;AAgBH;;;AAGG;AACG;;AAiFA;AAYN;;;;AAIG;;AAYH;;;;AAIG;;AAwBH;;;AAGG;;AAOH;;;AAGG;;AAOG;;;;AAoFN;AAoBA;;;AAGG;AACH;AAMA;AAaA;AAeA;AAOA;AAOA;AAkBA;AASA;AA+BA;;;AAkFA;;;;AAiBD;;ACx2BD;AAQE;AAEA;;;;AAQA;AAEA;AAGA;;;;;;;;;;;;;;;;;AAG+C;;;;;;;;;;;;;;;;;AAGD;AAG9C;AAEA;;;AAgBA;;;AAMD;;AC1DD;AAeI;AACA;;;;;;;AADQ;;;;;AAoBX;;ACjCD;;;AAGG;AACH;AAIA;;;;;;;;;;;;;;;;;AAiBG;AACG;AAKN;;;;;;;;;;;;;;;;;;;;;;AAsBG;AACH;AAOM;AACJ;;AAEG;;AAGH;;AAEG;;AAEJ;AAEK;AACJ;;AAEG;;AAEH;AACD;AAEK;AACJ;;AAEG;;AAEH;;AAEG;;AAEH;;AAEG;;AAEH;;AAEG;AACH;AACA;;AAEG;;AAEH;;;AAGG;AACH;AACD;;ACtGD;AAMI;AACA;;AAMF;;;AAcA;;;AAYD;;ACjBD;AA0Ic;;;;;AAjIZ;;AAEG;AACH;AAEA;;;AAGG;AACH;AAEA;;AAEG;AACH;AAEA;;AAEG;AACH;AAEA;;;AAGI;AACJ;AAIA;;AAEG;AACH;AAEA;;;AAGG;AACH;AAEA;;;;;AAKG;AACH;AAEA;;;;;AAKG;AACH;AAqCA;;AAEG;AACH;AAIA;;AAEG;AACH;AAEA;;;;;AAKG;AACH;AAYA;;;;AAQoB;AAyBpB;;;AAGG;AACH;AAQA;;AAEG;AACH;AAMA;;AAEG;AACH;AAqBA;;;;;;AAMG;;AAUH;;;AAGG;;AAMH;;;;;AAKG;;AAWH;;AAEG;;AAUH;;;;;AAKG;;AAKH;;;;;;;AAOG;AACH;AAmCA;;;;;;;AAOG;AACH;AAUA;;;;AAIG;AACH;;;AASD;;ACxXD;AAOE;;;AACD;;ACsBD;AA2EI;AACA;AACO;AACA;;;;AAlDT;AACA;;;;;AAKA;;;;AAIE;;;;AAIA;;;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACoE;AACpE;;AAKA;;AAEG;AACH;AAEA;;AAQA;;;;AAUU;AAMJ;AAmBN;;;;;;;;;;AA6IA;AAOA;AAgBA;AAcA;AAsBA;AAcA;;;AAiBD;;ACxWD;AAOE;AACA;AAGA;AAAkB;;;;;AAQnB;;ACfD;;AAgBE;AAEA;;;AAGD;;AC5BD;AAOE;;;;AAUD;;ACPD;AAiCI;AACA;AACA;AACA;AAbF;AACiE;AACjE;;;;;;AAQU;;;;;;;AAkEX;;ACjFD;;;;;;AAMG;AACH;;;;;AAgFC;;AC/GD;AACE;AACA;;;AA0BD;;ACvBD;AA+RI;AACA;AACA;AACA;AA5RF;;AAEA;;;;;;;AAuRU;;;;;AAuEV;;;AAGD;;AC1VD;;;;AAiByC;;ACpCzC;AA0Cc;AApCZ;AACA;;;AAmCoB;;AAUpB;;;AAGD;;ACvDD;;;;AAkBmD;;ACnBnD;AAOE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACoE;;;AACrE;;ACPD;AAOE;;;AAQA;AAOA;;;AAGD;;ACdD;AAmBE;AACA;AACA;AACA;AAEA;;AAEG;AAEH;AAEA;;AAEG;;AAIH;;AAEG;;AAIH;;AAEG;;AAIH;;AAEG;;AAIH;;;AAGG;AACH;AAEA;;AAEG;AACG;AAsCN;;;;AAIG;AACH;AAIA;;;AAGG;AACH;;;;;AAcD;;AC7ID;AAUA;;;;;AAqBC;;ACzBD;AAaE;AAEA;AAEA;;;AAMD;;ACjCD;AAOE;AACwB;AAExB;;;AAGD;;;"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { NgClass, JsonPipe, AsyncPipe, NgComponentOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { Input, Component, EventEmitter, inject, Output } from '@angular/core';
|
|
4
|
+
import { ListGroupComponent, ListItemComponent, ListItemCollapseComponent, ListItemBodyComponent, ListItemIconComponent, MarkdownToHtmlPipe, C8yTranslatePipe, GainsightService, AlertService, LoadingComponent, EmptyStateComponent, ContextRouteService } from '@c8y/ngx-components';
|
|
5
|
+
import { AIService } from '@c8y/ngx-components/ai';
|
|
6
|
+
import { AiChatComponent, AiChatSuggestionComponent, AiChatMessageComponent, AiChatMessageActionComponent } from '@c8y/ngx-components/ai/ai-chat';
|
|
7
|
+
import { gettext } from '@c8y/ngx-components/gettext';
|
|
8
|
+
import { BehaviorSubject, map, of } from 'rxjs';
|
|
9
|
+
import { WidgetConfigService, WidgetConfigFeedbackComponent } from '@c8y/ngx-components/context-dashboard';
|
|
10
|
+
|
|
11
|
+
class AgentStepFeedbackComponent {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.loading = false;
|
|
14
|
+
this.collapsed = true;
|
|
15
|
+
this.canCollapse = false;
|
|
16
|
+
}
|
|
17
|
+
ngOnInit() {
|
|
18
|
+
if (this.step) {
|
|
19
|
+
this.parseDefaultAgentStep(this.step);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
ngOnChanges(changes) {
|
|
23
|
+
if (changes.step) {
|
|
24
|
+
this.parseDefaultAgentStep(changes.step.currentValue);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
parseDefaultAgentStep(step) {
|
|
28
|
+
if (step.reasoning) {
|
|
29
|
+
this.label = gettext('Reasoning');
|
|
30
|
+
this.loading = false;
|
|
31
|
+
this.canCollapse = true;
|
|
32
|
+
this.collapsed = false;
|
|
33
|
+
}
|
|
34
|
+
if (step.toolCalls.length > 0 && !step.toolResults?.length) {
|
|
35
|
+
this.label = gettext('Calling a tool');
|
|
36
|
+
this.loading = true;
|
|
37
|
+
this.canCollapse = true;
|
|
38
|
+
this.collapsed = true;
|
|
39
|
+
}
|
|
40
|
+
else if (step.toolResults?.length > 0) {
|
|
41
|
+
this.label = gettext('Tool result');
|
|
42
|
+
this.loading = false;
|
|
43
|
+
this.canCollapse = true;
|
|
44
|
+
this.collapsed = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AgentStepFeedbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
48
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", type: AgentStepFeedbackComponent, isStandalone: true, selector: "c8y-agent-step-feedback", inputs: { step: "step", label: "label", loading: "loading", collapsed: "collapsed", canCollapse: "canCollapse" }, host: { classAttribute: "agent-step-feedback" }, usesOnChanges: true, ngImport: i0, template: "@if (!step.reasoning) {\n <div [innerHTML]=\"step.text | markdownToHtml | async\"></div>\n}\n@if (label) {\n <c8y-list-group class=\"m-t-16 m-b-16\">\n <c8y-li\n [active]=\"!loading\"\n [collapsed]=\"collapsed\"\n >\n <c8y-li-icon>\n <span\n class=\"btn-ai btn-ai-hint btn-sm\"\n [ngClass]=\"{ working: loading }\"\n >\n <span></span>\n </span>\n </c8y-li-icon>\n <c8y-li-body>\n {{ label | translate }}\n </c8y-li-body>\n\n @if (canCollapse) {\n <c8y-li-collapse>\n @if (step.reasoning) {\n <div [innerHTML]=\"step.reasoning | markdownToHtml | async\"></div>\n } @else if (step) {\n <pre\n class=\"fit-w\"\n style=\"max-height: 320px\"\n >{{ step | json }}</pre\n >\n }\n </c8y-li-collapse>\n }\n </c8y-li>\n </c8y-list-group>\n}\n", dependencies: [{ kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "component", type: ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "component", type: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: MarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
49
|
+
}
|
|
50
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AgentStepFeedbackComponent, decorators: [{
|
|
51
|
+
type: Component,
|
|
52
|
+
args: [{ selector: 'c8y-agent-step-feedback', standalone: true, imports: [
|
|
53
|
+
ListGroupComponent,
|
|
54
|
+
ListItemComponent,
|
|
55
|
+
ListItemCollapseComponent,
|
|
56
|
+
ListItemBodyComponent,
|
|
57
|
+
ListItemIconComponent,
|
|
58
|
+
NgClass,
|
|
59
|
+
JsonPipe,
|
|
60
|
+
MarkdownToHtmlPipe,
|
|
61
|
+
AsyncPipe,
|
|
62
|
+
C8yTranslatePipe
|
|
63
|
+
], host: { class: 'agent-step-feedback' }, template: "@if (!step.reasoning) {\n <div [innerHTML]=\"step.text | markdownToHtml | async\"></div>\n}\n@if (label) {\n <c8y-list-group class=\"m-t-16 m-b-16\">\n <c8y-li\n [active]=\"!loading\"\n [collapsed]=\"collapsed\"\n >\n <c8y-li-icon>\n <span\n class=\"btn-ai btn-ai-hint btn-sm\"\n [ngClass]=\"{ working: loading }\"\n >\n <span></span>\n </span>\n </c8y-li-icon>\n <c8y-li-body>\n {{ label | translate }}\n </c8y-li-body>\n\n @if (canCollapse) {\n <c8y-li-collapse>\n @if (step.reasoning) {\n <div [innerHTML]=\"step.reasoning | markdownToHtml | async\"></div>\n } @else if (step) {\n <pre\n class=\"fit-w\"\n style=\"max-height: 320px\"\n >{{ step | json }}</pre\n >\n }\n </c8y-li-collapse>\n }\n </c8y-li>\n </c8y-list-group>\n}\n" }]
|
|
64
|
+
}], propDecorators: { step: [{
|
|
65
|
+
type: Input,
|
|
66
|
+
args: [{ required: true }]
|
|
67
|
+
}], label: [{
|
|
68
|
+
type: Input
|
|
69
|
+
}], loading: [{
|
|
70
|
+
type: Input
|
|
71
|
+
}], collapsed: [{
|
|
72
|
+
type: Input
|
|
73
|
+
}], canCollapse: [{
|
|
74
|
+
type: Input
|
|
75
|
+
}] } });
|
|
76
|
+
|
|
77
|
+
class AgentChatComponent {
|
|
78
|
+
constructor() {
|
|
79
|
+
this.suggestions = [];
|
|
80
|
+
this.headline = gettext('Welcome!');
|
|
81
|
+
this.autoInstallAgents = true;
|
|
82
|
+
this.variables = {};
|
|
83
|
+
this.stepRenderComponent = AgentStepFeedbackComponent;
|
|
84
|
+
this.onMessageDelta = new EventEmitter();
|
|
85
|
+
this.onMessageText = new EventEmitter();
|
|
86
|
+
this.onMessageFinish = new EventEmitter();
|
|
87
|
+
this.onToolResult = new EventEmitter();
|
|
88
|
+
this.isLoading = false;
|
|
89
|
+
/**
|
|
90
|
+
* A stream of AI messages representing the conversation.
|
|
91
|
+
*/
|
|
92
|
+
this.messages$ = new BehaviorSubject([]);
|
|
93
|
+
this.hasError = true;
|
|
94
|
+
this.canCreate = false;
|
|
95
|
+
this.errorMsg = '';
|
|
96
|
+
this.prompt = '';
|
|
97
|
+
this.aiService = inject(AIService);
|
|
98
|
+
this.gainsightService = inject(GainsightService);
|
|
99
|
+
this.alertService = inject(AlertService);
|
|
100
|
+
this.defaultAgentStepRendererPipe = (source) => {
|
|
101
|
+
return source.pipe(map(steps => steps.map(step => {
|
|
102
|
+
if (step.reasoning || step.toolCalls || step.toolResults) {
|
|
103
|
+
return { content: this.stepRenderComponent, origin: { ...step } };
|
|
104
|
+
}
|
|
105
|
+
return { content: step.text, origin: { ...step } };
|
|
106
|
+
})));
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async ngOnInit() {
|
|
110
|
+
this.isLoading = true;
|
|
111
|
+
this.agentName = typeof this.agent === 'string' ? this.agent : this.agent.definitions[0].name;
|
|
112
|
+
try {
|
|
113
|
+
const agentHealth = await this.aiService.getAgentHealth(this.agentName);
|
|
114
|
+
this.composeErrorMessage(agentHealth);
|
|
115
|
+
if (typeof this.agent !== 'string' && this.agent.snapshot) {
|
|
116
|
+
this.createAgent();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (ex) {
|
|
120
|
+
this.errorMsg = gettext('Microservice not found. Please contact your administrator.');
|
|
121
|
+
this.hasError = true;
|
|
122
|
+
}
|
|
123
|
+
this.isLoading = false;
|
|
124
|
+
}
|
|
125
|
+
async sendMessage(message) {
|
|
126
|
+
this.messages$.next([...this.messages$.value, message]);
|
|
127
|
+
this.isLoading = true;
|
|
128
|
+
this.abortController = new AbortController();
|
|
129
|
+
const currentAssistantMessage = {
|
|
130
|
+
role: 'assistant',
|
|
131
|
+
content: ''
|
|
132
|
+
};
|
|
133
|
+
this.messages$.next([...this.messages$.value, currentAssistantMessage]);
|
|
134
|
+
const stream = await this.aiService.stream$(this.agentName, this.messages$.value.filter(m => m !== currentAssistantMessage), this.variables, this.abortController);
|
|
135
|
+
if (this.assistantSubscription) {
|
|
136
|
+
this.assistantSubscription.unsubscribe();
|
|
137
|
+
}
|
|
138
|
+
this.assistantSubscription = stream.subscribe((messageFromAssistant) => this.processAgentMessage(currentAssistantMessage, messageFromAssistant, this.agentName, message));
|
|
139
|
+
}
|
|
140
|
+
ngOnDestroy() {
|
|
141
|
+
this.cancel();
|
|
142
|
+
}
|
|
143
|
+
reprompt(userMessage) {
|
|
144
|
+
const index = this.messages$.value.indexOf(userMessage);
|
|
145
|
+
if (index > -1) {
|
|
146
|
+
this.messages$.next(this.messages$.value.slice(0, index));
|
|
147
|
+
this.prompt = userMessage.content;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
rate(assistantMessage, positive) {
|
|
151
|
+
const agentName = typeof this.agent === 'string' ? this.agent : this.agent.label;
|
|
152
|
+
this.gainsightService.triggerEvent('ai.agent.feedback', {
|
|
153
|
+
positive,
|
|
154
|
+
assistant: assistantMessage,
|
|
155
|
+
user: this.messages$.value[this.messages$.value.indexOf(assistantMessage) - 1],
|
|
156
|
+
agent: agentName
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
reload(assistantMessage) {
|
|
160
|
+
const index = this.messages$.value.indexOf(assistantMessage);
|
|
161
|
+
const userMessage = this.messages$.value[index - 1];
|
|
162
|
+
if (index > -1) {
|
|
163
|
+
this.messages$.next(this.messages$.value.slice(0, index - 1));
|
|
164
|
+
this.sendMessage({
|
|
165
|
+
role: 'user',
|
|
166
|
+
content: userMessage.content,
|
|
167
|
+
timestamp: new Date().toISOString()
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
cancel() {
|
|
172
|
+
if (this.abortController) {
|
|
173
|
+
this.abortController.abort();
|
|
174
|
+
}
|
|
175
|
+
if (this.assistantSubscription) {
|
|
176
|
+
this.assistantSubscription.unsubscribe();
|
|
177
|
+
}
|
|
178
|
+
this.isLoading = false;
|
|
179
|
+
}
|
|
180
|
+
async createAgent() {
|
|
181
|
+
this.isLoading = true;
|
|
182
|
+
try {
|
|
183
|
+
await this.aiService.createOrUpdateAgent(this.agent);
|
|
184
|
+
this.hasError = false;
|
|
185
|
+
}
|
|
186
|
+
catch (ex) {
|
|
187
|
+
this.alertService.danger(gettext('Failed to create the agent.'));
|
|
188
|
+
this.hasError = true;
|
|
189
|
+
}
|
|
190
|
+
this.isLoading = false;
|
|
191
|
+
}
|
|
192
|
+
composeErrorMessage(agentHealth) {
|
|
193
|
+
if (agentHealth.exists) {
|
|
194
|
+
this.errorMsg = '';
|
|
195
|
+
this.hasError = false;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
this.hasError = true;
|
|
199
|
+
if (!agentHealth.isProviderConfigured) {
|
|
200
|
+
this.errorMsg = gettext('AI provider is not configured. Please contact your administrator.');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (agentHealth.canCreate && typeof this.agent === 'string') {
|
|
204
|
+
this.errorMsg = gettext('The agent does not exist. Provide the agent definition in the agent manager to use it.');
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (agentHealth.canCreate && typeof this.agent !== 'string') {
|
|
208
|
+
this.canCreate = true;
|
|
209
|
+
if (this.autoInstallAgents) {
|
|
210
|
+
this.createAgent();
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
this.errorMsg = gettext('The agent does not exist. You can create it now.');
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (!agentHealth.canCreate) {
|
|
217
|
+
this.errorMsg = gettext('The agent does not exist. Please contact your administrator.');
|
|
218
|
+
if (agentHealth.messages?.length) {
|
|
219
|
+
this.errorMsg += '\n' + agentHealth.messages.join(' ');
|
|
220
|
+
}
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.errorMsg = gettext('Unknown error. Please contact your administrator.');
|
|
224
|
+
}
|
|
225
|
+
processAgentMessage(currentAssistantMessage, messageFromAssistant, agentName, message) {
|
|
226
|
+
currentAssistantMessage.content = messageFromAssistant.content;
|
|
227
|
+
const steps = messageFromAssistant.steps || [];
|
|
228
|
+
const lastStep = steps.length ? steps[steps.length - 1] : null;
|
|
229
|
+
this.onMessageDelta.emit(lastStep.textDelta);
|
|
230
|
+
this.onMessageText.emit(lastStep.text);
|
|
231
|
+
currentAssistantMessage.componentSteps$ = of(steps).pipe(this.defaultAgentStepRendererPipe);
|
|
232
|
+
if (messageFromAssistant.finishReason === 'stop') {
|
|
233
|
+
currentAssistantMessage.timestamp = new Date().toISOString();
|
|
234
|
+
this.onMessageFinish.emit(currentAssistantMessage.content);
|
|
235
|
+
this.gainsightService.triggerEvent('ai.agent.message', {
|
|
236
|
+
agent: agentName,
|
|
237
|
+
user: message,
|
|
238
|
+
assistant: currentAssistantMessage.content
|
|
239
|
+
});
|
|
240
|
+
this.isLoading = false;
|
|
241
|
+
}
|
|
242
|
+
if (messageFromAssistant.finishReason === 'error') {
|
|
243
|
+
currentAssistantMessage.timestamp = new Date().toISOString();
|
|
244
|
+
this.isLoading = false;
|
|
245
|
+
}
|
|
246
|
+
if (lastStep?.toolResults) {
|
|
247
|
+
lastStep.toolResults.forEach(toolResult => {
|
|
248
|
+
this.onToolResult.emit(toolResult);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// as we are mutating the currentAssistantMessage object
|
|
252
|
+
// which is already in the messages array we need to emit a new array reference
|
|
253
|
+
this.messages$.next([...this.messages$.value]);
|
|
254
|
+
}
|
|
255
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AgentChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
256
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", type: AgentChatComponent, isStandalone: true, selector: "c8y-agent-chat", inputs: { agent: "agent", suggestions: "suggestions", title: "title", headline: "headline", welcomeText: "welcomeText", autoInstallAgents: "autoInstallAgents", variables: "variables", stepRenderComponent: "stepRenderComponent" }, outputs: { onMessageDelta: "onMessageDelta", onMessageText: "onMessageText", onMessageFinish: "onMessageFinish", onToolResult: "onToolResult" }, ngImport: i0, template: "@if (hasError && isLoading) {\n <c8y-loading class=\"m-auto\"></c8y-loading>\n}\n@if (hasError && !isLoading) {\n <c8y-ui-empty-state\n class=\"m-auto\"\n [icon]=\"'disclaimer'\"\n [title]=\"'An error occurred' | translate\"\n [subtitle]=\"errorMsg | translate\"\n [horizontal]=\"true\"\n >\n @if (canCreate) {\n <div class=\"text-center m-t-16 m-b-16\">\n <button\n class=\"btn btn-primary\"\n (click)=\"createAgent()\"\n >\n {{ 'Create agent' | translate }}\n </button>\n </div>\n }\n </c8y-ui-empty-state>\n}\n\n@if (!hasError) {\n <c8y-ai-chat\n (onMessage)=\"sendMessage($event)\"\n [isLoading]=\"isLoading\"\n (onCancel)=\"cancel()\"\n [config]=\"{ title: title, headline: headline, welcomeText: welcomeText }\"\n [prompt]=\"prompt\"\n >\n @for (message of messages$ | async; track $index; let i = $index) {\n <c8y-ai-chat-message\n [message]=\"{ role: message.role, content: '', timestamp: message.timestamp }\"\n >\n @if (!message.componentSteps$) {\n <div [innerHTML]=\"message.content | markdownToHtml | async\"></div>\n }\n @for (step of message.componentSteps$ | async; track $index) {\n @if (typeof step.content === 'string') {\n <div [innerHTML]=\"step.content | markdownToHtml | async\"></div>\n } @else {\n <ng-container\n [ngComponentOutlet]=\"step.content\"\n [ngComponentOutletInputs]=\"{ step: step.origin }\"\n ></ng-container>\n }\n }\n\n @if (message.role === 'user') {\n <c8y-ai-chat-message-action\n icon=\"pencil\"\n [tooltip]=\"'Edit and resend this message' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"reprompt(message)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"thumbs-up\"\n [tooltip]=\"'This is useful' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"rate(message, true)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"thumbs-down\"\n [tooltip]=\"'This is not useful' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"rate(message, false)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"refresh\"\n [tooltip]=\"'Regenerate this response' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"reload(message)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (\n !message.content && message.role === 'assistant' && i === (messages$ | async)?.length - 1\n ) {\n <div class=\"text-center\">\n <c8y-loading></c8y-loading>\n </div>\n }\n </c8y-ai-chat-message>\n }\n\n @for (suggestion of suggestions; track $index) {\n <c8y-ai-chat-suggestion\n [icon]=\"suggestion.icon || 'c8y-bulb'\"\n [useAiButtons]=\"true\"\n [label]=\"suggestion.label\"\n [prompt]=\"suggestion.prompt\"\n (suggestionClicked)=\"sendMessage($event)\"\n [disabled]=\"isLoading\"\n ></c8y-ai-chat-suggestion>\n }\n </c8y-ai-chat>\n}\n", dependencies: [{ kind: "component", type: AiChatComponent, selector: "c8y-ai-chat", inputs: ["isLoading", "disabled", "prompt", "config"], outputs: ["onMessage", "onCancel"] }, { kind: "component", type: AiChatSuggestionComponent, selector: "c8y-ai-chat-suggestion", inputs: ["label", "prompt", "icon", "useAiButtons", "disabled"], outputs: ["suggestionClicked"] }, { kind: "component", type: AiChatMessageComponent, selector: "c8y-ai-chat-message", inputs: ["role", "message"] }, { kind: "component", type: AiChatMessageActionComponent, selector: "c8y-ai-chat-message-action", inputs: ["disabled", "tooltip", "icon"], outputs: ["click"] }, { kind: "component", type: LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: MarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
|
|
257
|
+
}
|
|
258
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AgentChatComponent, decorators: [{
|
|
259
|
+
type: Component,
|
|
260
|
+
args: [{ selector: 'c8y-agent-chat', imports: [
|
|
261
|
+
AiChatComponent,
|
|
262
|
+
AiChatSuggestionComponent,
|
|
263
|
+
AiChatMessageComponent,
|
|
264
|
+
AiChatMessageActionComponent,
|
|
265
|
+
LoadingComponent,
|
|
266
|
+
MarkdownToHtmlPipe,
|
|
267
|
+
AsyncPipe,
|
|
268
|
+
NgComponentOutlet,
|
|
269
|
+
C8yTranslatePipe,
|
|
270
|
+
EmptyStateComponent
|
|
271
|
+
], template: "@if (hasError && isLoading) {\n <c8y-loading class=\"m-auto\"></c8y-loading>\n}\n@if (hasError && !isLoading) {\n <c8y-ui-empty-state\n class=\"m-auto\"\n [icon]=\"'disclaimer'\"\n [title]=\"'An error occurred' | translate\"\n [subtitle]=\"errorMsg | translate\"\n [horizontal]=\"true\"\n >\n @if (canCreate) {\n <div class=\"text-center m-t-16 m-b-16\">\n <button\n class=\"btn btn-primary\"\n (click)=\"createAgent()\"\n >\n {{ 'Create agent' | translate }}\n </button>\n </div>\n }\n </c8y-ui-empty-state>\n}\n\n@if (!hasError) {\n <c8y-ai-chat\n (onMessage)=\"sendMessage($event)\"\n [isLoading]=\"isLoading\"\n (onCancel)=\"cancel()\"\n [config]=\"{ title: title, headline: headline, welcomeText: welcomeText }\"\n [prompt]=\"prompt\"\n >\n @for (message of messages$ | async; track $index; let i = $index) {\n <c8y-ai-chat-message\n [message]=\"{ role: message.role, content: '', timestamp: message.timestamp }\"\n >\n @if (!message.componentSteps$) {\n <div [innerHTML]=\"message.content | markdownToHtml | async\"></div>\n }\n @for (step of message.componentSteps$ | async; track $index) {\n @if (typeof step.content === 'string') {\n <div [innerHTML]=\"step.content | markdownToHtml | async\"></div>\n } @else {\n <ng-container\n [ngComponentOutlet]=\"step.content\"\n [ngComponentOutletInputs]=\"{ step: step.origin }\"\n ></ng-container>\n }\n }\n\n @if (message.role === 'user') {\n <c8y-ai-chat-message-action\n icon=\"pencil\"\n [tooltip]=\"'Edit and resend this message' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"reprompt(message)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"thumbs-up\"\n [tooltip]=\"'This is useful' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"rate(message, true)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"thumbs-down\"\n [tooltip]=\"'This is not useful' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"rate(message, false)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"refresh\"\n [tooltip]=\"'Regenerate this response' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"reload(message)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (\n !message.content && message.role === 'assistant' && i === (messages$ | async)?.length - 1\n ) {\n <div class=\"text-center\">\n <c8y-loading></c8y-loading>\n </div>\n }\n </c8y-ai-chat-message>\n }\n\n @for (suggestion of suggestions; track $index) {\n <c8y-ai-chat-suggestion\n [icon]=\"suggestion.icon || 'c8y-bulb'\"\n [useAiButtons]=\"true\"\n [label]=\"suggestion.label\"\n [prompt]=\"suggestion.prompt\"\n (suggestionClicked)=\"sendMessage($event)\"\n [disabled]=\"isLoading\"\n ></c8y-ai-chat-suggestion>\n }\n </c8y-ai-chat>\n}\n" }]
|
|
272
|
+
}], propDecorators: { agent: [{
|
|
273
|
+
type: Input,
|
|
274
|
+
args: [{ required: true }]
|
|
275
|
+
}], suggestions: [{
|
|
276
|
+
type: Input
|
|
277
|
+
}], title: [{
|
|
278
|
+
type: Input
|
|
279
|
+
}], headline: [{
|
|
280
|
+
type: Input
|
|
281
|
+
}], welcomeText: [{
|
|
282
|
+
type: Input
|
|
283
|
+
}], autoInstallAgents: [{
|
|
284
|
+
type: Input
|
|
285
|
+
}], variables: [{
|
|
286
|
+
type: Input
|
|
287
|
+
}], stepRenderComponent: [{
|
|
288
|
+
type: Input
|
|
289
|
+
}], onMessageDelta: [{
|
|
290
|
+
type: Output
|
|
291
|
+
}], onMessageText: [{
|
|
292
|
+
type: Output
|
|
293
|
+
}], onMessageFinish: [{
|
|
294
|
+
type: Output
|
|
295
|
+
}], onToolResult: [{
|
|
296
|
+
type: Output
|
|
297
|
+
}] } });
|
|
298
|
+
|
|
299
|
+
class WidgetAiChatSectionComponent {
|
|
300
|
+
constructor() {
|
|
301
|
+
this.suggestions = [];
|
|
302
|
+
this.headline = gettext('Welcome!');
|
|
303
|
+
this.title = gettext('What can I help you with?');
|
|
304
|
+
this.useContextAsVariable = true;
|
|
305
|
+
this.contextVariableName = 'c8yContext';
|
|
306
|
+
this.widgetConfigService = inject(WidgetConfigService);
|
|
307
|
+
this.alertService = inject(AlertService);
|
|
308
|
+
this.contextRouteService = inject(ContextRouteService);
|
|
309
|
+
/**
|
|
310
|
+
* A component that is used to render each step in the chat. By default, it uses the `AgentStepFeedbackComponent`.
|
|
311
|
+
* You can provide your own component by returning it from this callback.
|
|
312
|
+
*
|
|
313
|
+
* @returns A promise that resolves to a component type.
|
|
314
|
+
*/
|
|
315
|
+
this.loadRenderStepComponent = () => Promise.resolve(AgentStepFeedbackComponent);
|
|
316
|
+
/**
|
|
317
|
+
* A callback that is invoked when a tool result is returned. The function can return either:
|
|
318
|
+
* - `undefined` or `void`: No action is taken.
|
|
319
|
+
* - an object which is stored to the widget configuration.
|
|
320
|
+
*/
|
|
321
|
+
this.onToolResult = () => undefined;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* @ignore
|
|
325
|
+
*/
|
|
326
|
+
async ngOnInit() {
|
|
327
|
+
if (!this.variables && this.useContextAsVariable) {
|
|
328
|
+
const { contextData } = this.contextRouteService.activatedContextData;
|
|
329
|
+
this.variables = {
|
|
330
|
+
[this.contextVariableName]: contextData || this.widgetConfigService.currentConfig.device
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
this._renderStepComponent = await this.loadRenderStepComponent();
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Handles the tool result returned from the AI agent.
|
|
337
|
+
* @param tool The tool result returned from the AI agent.
|
|
338
|
+
*/
|
|
339
|
+
toolResultHandler(tool) {
|
|
340
|
+
try {
|
|
341
|
+
const parsedResult = this.onToolResult(tool);
|
|
342
|
+
if (!parsedResult) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
this.widgetConfigService.updateConfig({
|
|
346
|
+
config: {
|
|
347
|
+
...this.widgetConfigService.currentConfig,
|
|
348
|
+
...parsedResult
|
|
349
|
+
}
|
|
350
|
+
}, true);
|
|
351
|
+
}
|
|
352
|
+
catch (e) {
|
|
353
|
+
this.alertService.danger(gettext('There was an error processing the AI response.'));
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: WidgetAiChatSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
357
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.3", type: WidgetAiChatSectionComponent, isStandalone: true, selector: "c8y-widget-ai-chat-section", inputs: { suggestions: "suggestions", agent: "agent", headline: "headline", title: "title", welcomeText: "welcomeText", variables: "variables", useContextAsVariable: "useContextAsVariable", contextVariableName: "contextVariableName", loadRenderStepComponent: "loadRenderStepComponent" }, ngImport: i0, template: "<c8y-widget-config-feedback>\n <div\n class=\"m-l-4 btn-ai btn-ai-hint btn-sm\"\n [title]=\"'AI code assistant' | translate\"\n >\n <span></span>\n </div>\n</c8y-widget-config-feedback>\n\n<c8y-agent-chat\n [title]=\"title | translate\"\n [headline]=\"headline | translate\"\n [welcomeText]=\"welcomeText | translate\"\n #agentChat\n [suggestions]=\"(agentChat.messages$ | async)?.length === 0 ? suggestions : []\"\n [agent]=\"agent\"\n [variables]=\"variables\"\n [stepRenderComponent]=\"_renderStepComponent\"\n (onToolResult)=\"toolResultHandler($event)\"\n></c8y-agent-chat>\n", dependencies: [{ kind: "component", type: AgentChatComponent, selector: "c8y-agent-chat", inputs: ["agent", "suggestions", "title", "headline", "welcomeText", "autoInstallAgents", "variables", "stepRenderComponent"], outputs: ["onMessageDelta", "onMessageText", "onMessageFinish", "onToolResult"] }, { kind: "component", type: WidgetConfigFeedbackComponent, selector: "c8y-widget-config-feedback" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
358
|
+
}
|
|
359
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: WidgetAiChatSectionComponent, decorators: [{
|
|
360
|
+
type: Component,
|
|
361
|
+
args: [{ selector: 'c8y-widget-ai-chat-section', imports: [AgentChatComponent, C8yTranslatePipe, AsyncPipe, WidgetConfigFeedbackComponent], standalone: true, template: "<c8y-widget-config-feedback>\n <div\n class=\"m-l-4 btn-ai btn-ai-hint btn-sm\"\n [title]=\"'AI code assistant' | translate\"\n >\n <span></span>\n </div>\n</c8y-widget-config-feedback>\n\n<c8y-agent-chat\n [title]=\"title | translate\"\n [headline]=\"headline | translate\"\n [welcomeText]=\"welcomeText | translate\"\n #agentChat\n [suggestions]=\"(agentChat.messages$ | async)?.length === 0 ? suggestions : []\"\n [agent]=\"agent\"\n [variables]=\"variables\"\n [stepRenderComponent]=\"_renderStepComponent\"\n (onToolResult)=\"toolResultHandler($event)\"\n></c8y-agent-chat>\n" }]
|
|
362
|
+
}], propDecorators: { suggestions: [{
|
|
363
|
+
type: Input
|
|
364
|
+
}], agent: [{
|
|
365
|
+
type: Input
|
|
366
|
+
}], headline: [{
|
|
367
|
+
type: Input
|
|
368
|
+
}], title: [{
|
|
369
|
+
type: Input
|
|
370
|
+
}], welcomeText: [{
|
|
371
|
+
type: Input
|
|
372
|
+
}], variables: [{
|
|
373
|
+
type: Input
|
|
374
|
+
}], useContextAsVariable: [{
|
|
375
|
+
type: Input
|
|
376
|
+
}], contextVariableName: [{
|
|
377
|
+
type: Input
|
|
378
|
+
}], loadRenderStepComponent: [{
|
|
379
|
+
type: Input
|
|
380
|
+
}] } });
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Generated bundle index. Do not edit.
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
export { AgentChatComponent, AgentStepFeedbackComponent, WidgetAiChatSectionComponent };
|
|
387
|
+
//# sourceMappingURL=c8y-ngx-components-ai-agent-chat.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"c8y-ngx-components-ai-agent-chat.mjs","sources":["../../ai/agent-chat/agent-step-feedback.component.ts","../../ai/agent-chat/agent-step-feedback.component.html","../../ai/agent-chat/agent-chat.component.ts","../../ai/agent-chat/agent-chat.component.html","../../ai/agent-chat/widget-ai-chat-section.component.ts","../../ai/agent-chat/widget-ai-chat-section.component.html","../../ai/agent-chat/c8y-ngx-components-ai-agent-chat.ts"],"sourcesContent":["import { JsonPipe, NgClass, AsyncPipe } from '@angular/common';\nimport { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';\nimport {\n ListGroupComponent,\n ListItemBodyComponent,\n ListItemCollapseComponent,\n ListItemComponent,\n ListItemIconComponent,\n MarkdownToHtmlPipe,\n C8yTranslatePipe\n} from '@c8y/ngx-components';\nimport { AgentStep } from '@c8y/ngx-components/ai';\nimport { gettext } from '@c8y/ngx-components/gettext';\n\n@Component({\n selector: 'c8y-agent-step-feedback',\n templateUrl: './agent-step-feedback.component.html',\n standalone: true,\n imports: [\n ListGroupComponent,\n ListItemComponent,\n ListItemCollapseComponent,\n ListItemBodyComponent,\n ListItemIconComponent,\n NgClass,\n JsonPipe,\n MarkdownToHtmlPipe,\n AsyncPipe,\n C8yTranslatePipe\n ],\n host: { class: 'agent-step-feedback' }\n})\nexport class AgentStepFeedbackComponent implements OnInit, OnChanges {\n @Input({ required: true }) step: AgentStep;\n\n @Input() label: string;\n @Input() loading = false;\n @Input() collapsed = true;\n @Input() canCollapse = false;\n\n ngOnInit(): void {\n if (this.step) {\n this.parseDefaultAgentStep(this.step);\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes.step) {\n this.parseDefaultAgentStep(changes.step.currentValue);\n }\n }\n\n parseDefaultAgentStep(step: AgentStep): void {\n if (step.reasoning) {\n this.label = gettext('Reasoning');\n this.loading = false;\n this.canCollapse = true;\n this.collapsed = false;\n }\n\n if (step.toolCalls.length > 0 && !step.toolResults?.length) {\n this.label = gettext('Calling a tool');\n this.loading = true;\n this.canCollapse = true;\n this.collapsed = true;\n } else if (step.toolResults?.length > 0) {\n this.label = gettext('Tool result');\n this.loading = false;\n this.canCollapse = true;\n this.collapsed = true;\n }\n }\n}\n","@if (!step.reasoning) {\n <div [innerHTML]=\"step.text | markdownToHtml | async\"></div>\n}\n@if (label) {\n <c8y-list-group class=\"m-t-16 m-b-16\">\n <c8y-li\n [active]=\"!loading\"\n [collapsed]=\"collapsed\"\n >\n <c8y-li-icon>\n <span\n class=\"btn-ai btn-ai-hint btn-sm\"\n [ngClass]=\"{ working: loading }\"\n >\n <span></span>\n </span>\n </c8y-li-icon>\n <c8y-li-body>\n {{ label | translate }}\n </c8y-li-body>\n\n @if (canCollapse) {\n <c8y-li-collapse>\n @if (step.reasoning) {\n <div [innerHTML]=\"step.reasoning | markdownToHtml | async\"></div>\n } @else if (step) {\n <pre\n class=\"fit-w\"\n style=\"max-height: 320px\"\n >{{ step | json }}</pre\n >\n }\n </c8y-li-collapse>\n }\n </c8y-li>\n </c8y-list-group>\n}\n","import { AsyncPipe, NgComponentOutlet } from '@angular/common';\nimport {\n Component,\n EventEmitter,\n inject,\n Input,\n OnDestroy,\n OnInit,\n Output,\n Type\n} from '@angular/core';\nimport {\n AlertService,\n C8yTranslatePipe,\n EmptyStateComponent,\n GainsightService,\n LoadingComponent,\n MarkdownToHtmlPipe\n} from '@c8y/ngx-components';\nimport {\n AgentHealthCheckResponse,\n AgentStep,\n AIMessage,\n AIMessageStreamSteps,\n AIService,\n ClientAgentDefinition,\n ToolResult\n} from '@c8y/ngx-components/ai';\nimport {\n AiChatComponent,\n AiChatMessageActionComponent,\n AiChatMessageComponent,\n AiChatSuggestionComponent\n} from '@c8y/ngx-components/ai/ai-chat';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { BehaviorSubject, map, Observable, of, OperatorFunction, Subscription } from 'rxjs';\nimport { AgentStepFeedbackComponent } from './agent-step-feedback.component';\n\n@Component({\n selector: 'c8y-agent-chat',\n templateUrl: './agent-chat.component.html',\n imports: [\n AiChatComponent,\n AiChatSuggestionComponent,\n AiChatMessageComponent,\n AiChatMessageActionComponent,\n LoadingComponent,\n MarkdownToHtmlPipe,\n AsyncPipe,\n NgComponentOutlet,\n C8yTranslatePipe,\n EmptyStateComponent\n ]\n})\nexport class AgentChatComponent implements OnInit, OnDestroy {\n @Input({ required: true }) agent: string | ClientAgentDefinition;\n @Input() suggestions: { label: string; prompt: string; icon?: string }[] = [];\n @Input() title: string;\n @Input() headline: string = gettext('Welcome!');\n @Input() welcomeText: string;\n @Input() autoInstallAgents = true;\n @Input() variables = {};\n @Input() stepRenderComponent: Type<any> = AgentStepFeedbackComponent;\n\n @Output() onMessageDelta = new EventEmitter<string>();\n @Output() onMessageText = new EventEmitter<string>();\n @Output() onMessageFinish = new EventEmitter<string>();\n @Output() onToolResult = new EventEmitter<ToolResult>();\n\n isLoading = false;\n\n /**\n * A stream of AI messages representing the conversation.\n */\n messages$: BehaviorSubject<AIMessageStreamSteps[]> = new BehaviorSubject<AIMessageStreamSteps[]>(\n []\n );\n agentName: string;\n hasError = true;\n canCreate = false;\n errorMsg = '';\n prompt = '';\n\n private aiService = inject(AIService);\n private gainsightService = inject(GainsightService);\n private alertService = inject(AlertService);\n private abortController: AbortController;\n private assistantSubscription: Subscription;\n\n defaultAgentStepRendererPipe: OperatorFunction<\n AgentStep[],\n { content: Type<any> | string; origin: AgentStep }[]\n > = <T extends AgentStep[]>(source: Observable<T>) => {\n return source.pipe(\n map(steps =>\n steps.map(step => {\n if (step.reasoning || step.toolCalls || step.toolResults) {\n return { content: this.stepRenderComponent, origin: { ...step } };\n }\n return { content: step.text, origin: { ...step } };\n })\n )\n );\n };\n\n async ngOnInit(): Promise<void> {\n this.isLoading = true;\n this.agentName = typeof this.agent === 'string' ? this.agent : this.agent.definitions[0].name;\n try {\n const agentHealth: AgentHealthCheckResponse = await this.aiService.getAgentHealth(\n this.agentName\n );\n this.composeErrorMessage(agentHealth);\n if (typeof this.agent !== 'string' && this.agent.snapshot) {\n this.createAgent();\n }\n } catch (ex) {\n this.errorMsg = gettext('Microservice not found. Please contact your administrator.');\n this.hasError = true;\n }\n this.isLoading = false;\n }\n\n async sendMessage(message: AIMessage) {\n this.messages$.next([...this.messages$.value, message]);\n this.isLoading = true;\n this.abortController = new AbortController();\n const currentAssistantMessage: AIMessageStreamSteps = {\n role: 'assistant',\n content: ''\n };\n this.messages$.next([...this.messages$.value, currentAssistantMessage]);\n const stream = await this.aiService.stream$(\n this.agentName,\n this.messages$.value.filter(m => m !== currentAssistantMessage),\n this.variables,\n this.abortController\n );\n\n if (this.assistantSubscription) {\n this.assistantSubscription.unsubscribe();\n }\n\n this.assistantSubscription = stream.subscribe((messageFromAssistant: AIMessage) =>\n this.processAgentMessage(\n currentAssistantMessage,\n messageFromAssistant,\n this.agentName,\n message\n )\n );\n }\n\n ngOnDestroy(): void {\n this.cancel();\n }\n\n reprompt(userMessage: AIMessageStreamSteps) {\n const index = this.messages$.value.indexOf(userMessage);\n if (index > -1) {\n this.messages$.next(this.messages$.value.slice(0, index));\n this.prompt = userMessage.content;\n }\n }\n\n rate(assistantMessage: AIMessageStreamSteps, positive) {\n const agentName = typeof this.agent === 'string' ? this.agent : this.agent.label;\n this.gainsightService.triggerEvent('ai.agent.feedback', {\n positive,\n assistant: assistantMessage,\n user: this.messages$.value[this.messages$.value.indexOf(assistantMessage) - 1],\n agent: agentName\n });\n }\n\n reload(assistantMessage: AIMessageStreamSteps) {\n const index = this.messages$.value.indexOf(assistantMessage);\n const userMessage = this.messages$.value[index - 1];\n if (index > -1) {\n this.messages$.next(this.messages$.value.slice(0, index - 1));\n this.sendMessage({\n role: 'user',\n content: userMessage.content,\n timestamp: new Date().toISOString()\n });\n }\n }\n\n cancel() {\n if (this.abortController) {\n this.abortController.abort();\n }\n if (this.assistantSubscription) {\n this.assistantSubscription.unsubscribe();\n }\n this.isLoading = false;\n }\n\n async createAgent() {\n this.isLoading = true;\n try {\n await this.aiService.createOrUpdateAgent(this.agent as ClientAgentDefinition);\n this.hasError = false;\n } catch (ex) {\n this.alertService.danger(gettext('Failed to create the agent.'));\n this.hasError = true;\n }\n this.isLoading = false;\n }\n\n private composeErrorMessage(agentHealth: AgentHealthCheckResponse) {\n if (agentHealth.exists) {\n this.errorMsg = '';\n this.hasError = false;\n return;\n }\n this.hasError = true;\n if (!agentHealth.isProviderConfigured) {\n this.errorMsg = gettext('AI provider is not configured. Please contact your administrator.');\n return;\n }\n if (agentHealth.canCreate && typeof this.agent === 'string') {\n this.errorMsg = gettext(\n 'The agent does not exist. Provide the agent definition in the agent manager to use it.'\n );\n return;\n }\n if (agentHealth.canCreate && typeof this.agent !== 'string') {\n this.canCreate = true;\n if (this.autoInstallAgents) {\n this.createAgent();\n return;\n }\n this.errorMsg = gettext('The agent does not exist. You can create it now.');\n return;\n }\n if (!agentHealth.canCreate) {\n this.errorMsg = gettext('The agent does not exist. Please contact your administrator.');\n if (agentHealth.messages?.length) {\n this.errorMsg += '\\n' + agentHealth.messages.join(' ');\n }\n return;\n }\n this.errorMsg = gettext('Unknown error. Please contact your administrator.');\n }\n\n private processAgentMessage(\n currentAssistantMessage: AIMessageStreamSteps,\n messageFromAssistant: AIMessage,\n agentName: string,\n message: AIMessage\n ) {\n currentAssistantMessage.content = messageFromAssistant.content;\n\n const steps = messageFromAssistant.steps || [];\n const lastStep = steps.length ? steps[steps.length - 1] : null;\n\n this.onMessageDelta.emit(lastStep.textDelta);\n this.onMessageText.emit(lastStep.text);\n currentAssistantMessage.componentSteps$ = of(steps).pipe(this.defaultAgentStepRendererPipe);\n\n if (messageFromAssistant.finishReason === 'stop') {\n currentAssistantMessage.timestamp = new Date().toISOString();\n this.onMessageFinish.emit(currentAssistantMessage.content);\n this.gainsightService.triggerEvent('ai.agent.message', {\n agent: agentName,\n user: message,\n assistant: currentAssistantMessage.content\n });\n this.isLoading = false;\n }\n\n if (messageFromAssistant.finishReason === 'error') {\n currentAssistantMessage.timestamp = new Date().toISOString();\n this.isLoading = false;\n }\n\n if (lastStep?.toolResults) {\n lastStep.toolResults.forEach(toolResult => {\n this.onToolResult.emit(toolResult);\n });\n }\n\n // as we are mutating the currentAssistantMessage object\n // which is already in the messages array we need to emit a new array reference\n this.messages$.next([...this.messages$.value]);\n }\n}\n","@if (hasError && isLoading) {\n <c8y-loading class=\"m-auto\"></c8y-loading>\n}\n@if (hasError && !isLoading) {\n <c8y-ui-empty-state\n class=\"m-auto\"\n [icon]=\"'disclaimer'\"\n [title]=\"'An error occurred' | translate\"\n [subtitle]=\"errorMsg | translate\"\n [horizontal]=\"true\"\n >\n @if (canCreate) {\n <div class=\"text-center m-t-16 m-b-16\">\n <button\n class=\"btn btn-primary\"\n (click)=\"createAgent()\"\n >\n {{ 'Create agent' | translate }}\n </button>\n </div>\n }\n </c8y-ui-empty-state>\n}\n\n@if (!hasError) {\n <c8y-ai-chat\n (onMessage)=\"sendMessage($event)\"\n [isLoading]=\"isLoading\"\n (onCancel)=\"cancel()\"\n [config]=\"{ title: title, headline: headline, welcomeText: welcomeText }\"\n [prompt]=\"prompt\"\n >\n @for (message of messages$ | async; track $index; let i = $index) {\n <c8y-ai-chat-message\n [message]=\"{ role: message.role, content: '', timestamp: message.timestamp }\"\n >\n @if (!message.componentSteps$) {\n <div [innerHTML]=\"message.content | markdownToHtml | async\"></div>\n }\n @for (step of message.componentSteps$ | async; track $index) {\n @if (typeof step.content === 'string') {\n <div [innerHTML]=\"step.content | markdownToHtml | async\"></div>\n } @else {\n <ng-container\n [ngComponentOutlet]=\"step.content\"\n [ngComponentOutletInputs]=\"{ step: step.origin }\"\n ></ng-container>\n }\n }\n\n @if (message.role === 'user') {\n <c8y-ai-chat-message-action\n icon=\"pencil\"\n [tooltip]=\"'Edit and resend this message' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"reprompt(message)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"thumbs-up\"\n [tooltip]=\"'This is useful' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"rate(message, true)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"thumbs-down\"\n [tooltip]=\"'This is not useful' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"rate(message, false)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (message.role === 'assistant' && (i < (messages$ | async)?.length - 1 || !isLoading)) {\n <c8y-ai-chat-message-action\n icon=\"refresh\"\n [tooltip]=\"'Regenerate this response' | translate\"\n [disabled]=\"isLoading\"\n (click)=\"reload(message)\"\n ></c8y-ai-chat-message-action>\n }\n\n @if (\n !message.content && message.role === 'assistant' && i === (messages$ | async)?.length - 1\n ) {\n <div class=\"text-center\">\n <c8y-loading></c8y-loading>\n </div>\n }\n </c8y-ai-chat-message>\n }\n\n @for (suggestion of suggestions; track $index) {\n <c8y-ai-chat-suggestion\n [icon]=\"suggestion.icon || 'c8y-bulb'\"\n [useAiButtons]=\"true\"\n [label]=\"suggestion.label\"\n [prompt]=\"suggestion.prompt\"\n (suggestionClicked)=\"sendMessage($event)\"\n [disabled]=\"isLoading\"\n ></c8y-ai-chat-suggestion>\n }\n </c8y-ai-chat>\n}\n","import { AsyncPipe } from '@angular/common';\nimport { Component, inject, Input, OnInit, Type } from '@angular/core';\nimport { AlertService, C8yTranslatePipe, ContextRouteService } from '@c8y/ngx-components';\nimport { gettext } from '@c8y/ngx-components/gettext';\nimport { ClientAgentDefinition, ToolResult } from '@c8y/ngx-components/ai';\nimport {\n WidgetConfigFeedbackComponent,\n WidgetConfigService\n} from '@c8y/ngx-components/context-dashboard';\nimport { AgentChatComponent } from './agent-chat.component';\nimport { AgentStepFeedbackComponent } from './agent-step-feedback.component';\n\n@Component({\n selector: 'c8y-widget-ai-chat-section',\n imports: [AgentChatComponent, C8yTranslatePipe, AsyncPipe, WidgetConfigFeedbackComponent],\n standalone: true,\n templateUrl: './widget-ai-chat-section.component.html'\n})\nexport class WidgetAiChatSectionComponent implements OnInit {\n @Input()\n suggestions: Array<{ label: string; prompt: string }> = [];\n @Input()\n agent: string | ClientAgentDefinition;\n @Input()\n headline = gettext('Welcome!');\n @Input()\n title: string = gettext('What can I help you with?');\n @Input()\n welcomeText;\n @Input()\n variables: { [key: string]: any };\n @Input()\n useContextAsVariable = true;\n @Input()\n contextVariableName = 'c8yContext';\n _renderStepComponent: Type<any>;\n\n private readonly widgetConfigService = inject(WidgetConfigService);\n private readonly alertService = inject(AlertService);\n private readonly contextRouteService = inject(ContextRouteService);\n\n /**\n * A component that is used to render each step in the chat. By default, it uses the `AgentStepFeedbackComponent`.\n * You can provide your own component by returning it from this callback.\n *\n * @returns A promise that resolves to a component type.\n */\n @Input()\n loadRenderStepComponent: () => Promise<Type<any>> = () =>\n Promise.resolve(AgentStepFeedbackComponent);\n\n /**\n * A callback that is invoked when a tool result is returned. The function can return either:\n * - `undefined` or `void`: No action is taken.\n * - an object which is stored to the widget configuration.\n */\n onToolResult: (step: ToolResult) => undefined | any = () => undefined;\n\n /**\n * @ignore\n */\n async ngOnInit(): Promise<void> {\n if (!this.variables && this.useContextAsVariable) {\n const { contextData } = this.contextRouteService.activatedContextData;\n this.variables = {\n [this.contextVariableName]: contextData || this.widgetConfigService.currentConfig.device\n };\n }\n\n this._renderStepComponent = await this.loadRenderStepComponent();\n }\n\n /**\n * Handles the tool result returned from the AI agent.\n * @param tool The tool result returned from the AI agent.\n */\n toolResultHandler(tool: ToolResult) {\n try {\n const parsedResult = this.onToolResult(tool);\n if (!parsedResult) {\n return;\n }\n this.widgetConfigService.updateConfig(\n {\n config: {\n ...this.widgetConfigService.currentConfig,\n ...parsedResult\n }\n },\n true\n );\n } catch (e) {\n this.alertService.danger(gettext('There was an error processing the AI response.'));\n }\n }\n}\n","<c8y-widget-config-feedback>\n <div\n class=\"m-l-4 btn-ai btn-ai-hint btn-sm\"\n [title]=\"'AI code assistant' | translate\"\n >\n <span></span>\n </div>\n</c8y-widget-config-feedback>\n\n<c8y-agent-chat\n [title]=\"title | translate\"\n [headline]=\"headline | translate\"\n [welcomeText]=\"welcomeText | translate\"\n #agentChat\n [suggestions]=\"(agentChat.messages$ | async)?.length === 0 ? suggestions : []\"\n [agent]=\"agent\"\n [variables]=\"variables\"\n [stepRenderComponent]=\"_renderStepComponent\"\n (onToolResult)=\"toolResultHandler($event)\"\n></c8y-agent-chat>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|