import { NgClass, JsonPipe, AsyncPipe, NgComponentOutlet } from '@angular/common';
import * as i0 from '@angular/core';
import { Input, Component, EventEmitter, inject, Output } from '@angular/core';
import { ListGroupComponent, ListItemComponent, ListItemCollapseComponent, ListItemBodyComponent, ListItemIconComponent, MarkdownToHtmlPipe, C8yTranslatePipe, GainsightService, AlertService, LoadingComponent, EmptyStateComponent, ContextRouteService } from '@c8y/ngx-components';
import { AIService } from '@c8y/ngx-components/ai';
import { AiChatComponent, AiChatSuggestionComponent, AiChatMessageComponent, AiChatMessageActionComponent } from '@c8y/ngx-components/ai/ai-chat';
import { gettext } from '@c8y/ngx-components/gettext';
import { BehaviorSubject, map, firstValueFrom, of } from 'rxjs';
import { WidgetConfigService, WidgetConfigFeedbackComponent } from '@c8y/ngx-components/context-dashboard';

class AgentStepFeedbackComponent {
    constructor() {
        this.loading = false;
        this.collapsed = true;
        this.canCollapse = false;
    }
    ngOnInit() {
        if (this.step) {
            this.parseDefaultAgentStep(this.step);
        }
    }
    ngOnChanges(changes) {
        if (changes.step) {
            this.parseDefaultAgentStep(changes.step.currentValue);
        }
    }
    parseDefaultAgentStep(step) {
        if (step.reasoning) {
            this.label = gettext('Reasoning');
            this.loading = false;
            this.canCollapse = true;
            this.collapsed = false;
        }
        if (step.toolCalls.length > 0 && !step.toolResults?.length) {
            this.label = gettext('Calling a tool');
            this.loading = true;
            this.canCollapse = true;
            this.collapsed = true;
        }
        else if (step.toolResults?.length > 0) {
            this.label = gettext('Tool result');
            this.loading = false;
            this.canCollapse = true;
            this.collapsed = true;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AgentStepFeedbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AgentStepFeedbackComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-agent-step-feedback', standalone: true, imports: [
                        ListGroupComponent,
                        ListItemComponent,
                        ListItemCollapseComponent,
                        ListItemBodyComponent,
                        ListItemIconComponent,
                        NgClass,
                        JsonPipe,
                        MarkdownToHtmlPipe,
                        AsyncPipe,
                        C8yTranslatePipe
                    ], 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" }]
        }], propDecorators: { step: [{
                type: Input,
                args: [{ required: true }]
            }], label: [{
                type: Input
            }], loading: [{
                type: Input
            }], collapsed: [{
                type: Input
            }], canCollapse: [{
                type: Input
            }] } });

class AgentChatComponent {
    constructor() {
        this.suggestions = [];
        this.headline = gettext('Welcome!');
        this.autoInstallAgents = true;
        this.variables = {};
        this.stepRenderComponent = AgentStepFeedbackComponent;
        this.onMessageDelta = new EventEmitter();
        this.onMessageText = new EventEmitter();
        this.onMessageFinish = new EventEmitter();
        this.onToolResult = new EventEmitter();
        this.isLoading = false;
        /**
         * A stream of AI messages representing the conversation.
         */
        this.messages$ = new BehaviorSubject([]);
        this.hasError = true;
        this.canCreate = false;
        this.errorMsg = '';
        this.prompt = '';
        this.aiService = inject(AIService);
        this.gainsightService = inject(GainsightService);
        this.alertService = inject(AlertService);
        this.defaultAgentStepRendererPipe = (source) => {
            return source.pipe(map(steps => steps.map(step => {
                if (step.reasoning || step.toolCalls || step.toolResults) {
                    return { content: this.stepRenderComponent, origin: { ...step } };
                }
                return { content: step.text, origin: { ...step } };
            })));
        };
    }
    async ngOnInit() {
        this.isLoading = true;
        this.agentName = typeof this.agent === 'string' ? this.agent : this.agent.definitions[0].name;
        try {
            const agentHealth = await this.aiService.getAgentHealth(this.agentName);
            this.composeErrorMessage(agentHealth);
            if (typeof this.agent !== 'string' && this.agent.snapshot) {
                this.createAgent();
            }
        }
        catch (ex) {
            this.errorMsg = gettext('Microservice not found. Please contact your administrator.');
            this.hasError = true;
        }
        this.isLoading = false;
    }
    async sendMessage(message) {
        this.messages$.next([...this.messages$.value, message]);
        this.isLoading = true;
        this.abortController = new AbortController();
        const currentAssistantMessage = {
            role: 'assistant',
            content: ''
        };
        this.messages$.next([...this.messages$.value, currentAssistantMessage]);
        const stream = await this.aiService.stream$(this.agentName, this.messages$.value.filter(m => m !== currentAssistantMessage), this.variables, this.abortController);
        if (this.assistantSubscription) {
            this.assistantSubscription.unsubscribe();
        }
        this.assistantSubscription = stream.subscribe((messageFromAssistant) => this.processAgentMessage(currentAssistantMessage, messageFromAssistant, this.agentName, message));
    }
    ngOnDestroy() {
        this.cancel();
    }
    reprompt(userMessage) {
        const index = this.messages$.value.indexOf(userMessage);
        if (index > -1) {
            this.messages$.next(this.messages$.value.slice(0, index));
            this.prompt = userMessage.content;
        }
    }
    rate(assistantMessage, positive) {
        const agentName = typeof this.agent === 'string' ? this.agent : this.agent.label;
        this.gainsightService.triggerEvent('ai.agent.feedback', {
            positive,
            assistant: assistantMessage,
            user: this.messages$.value[this.messages$.value.indexOf(assistantMessage) - 1],
            agent: agentName
        });
    }
    reload(assistantMessage) {
        const index = this.messages$.value.indexOf(assistantMessage);
        const userMessage = this.messages$.value[index - 1];
        if (index > -1) {
            this.messages$.next(this.messages$.value.slice(0, index - 1));
            this.sendMessage({
                role: 'user',
                content: userMessage.content,
                timestamp: new Date().toISOString()
            });
        }
    }
    async cancel() {
        if (this.abortController) {
            this.abortController.abort();
        }
        const lastMessage = this.messages$.value[this.messages$.value.length - 1];
        if (lastMessage && lastMessage.role === 'assistant') {
            if (lastMessage.content === '') {
                // if message is aborted before content is even populated, remove it entirely
                this.messages$.next(this.messages$.value.slice(0, -1));
            }
            else {
                // if message has content, mark the last step as aborted to indicate incomplete processing
                const lastMessageSteps = (await firstValueFrom(lastMessage.componentSteps$))
                    .map(s => s.origin)
                    .map((step, index, arr) => index === arr.length - 1 ? { ...step, aborted: true } : step) || [];
                if (lastMessageSteps.length) {
                    lastMessage.componentSteps$ = of(lastMessageSteps).pipe(this.defaultAgentStepRendererPipe);
                    this.messages$.next([...this.messages$.value]);
                }
            }
        }
        if (this.assistantSubscription) {
            this.assistantSubscription.unsubscribe();
        }
        this.isLoading = false;
    }
    async createAgent() {
        this.isLoading = true;
        try {
            await this.aiService.createOrUpdateAgent(this.agent);
            this.hasError = false;
        }
        catch (ex) {
            this.alertService.danger(gettext('Failed to create the agent.'));
            this.hasError = true;
        }
        this.isLoading = false;
    }
    composeErrorMessage(agentHealth) {
        if (agentHealth.exists) {
            this.errorMsg = '';
            this.hasError = false;
            return;
        }
        this.hasError = true;
        if (!agentHealth.isProviderConfigured) {
            this.errorMsg = gettext('AI provider is not configured. Please contact your administrator.');
            return;
        }
        if (agentHealth.canCreate && typeof this.agent === 'string') {
            this.errorMsg = gettext('The agent does not exist. Provide the agent definition in the agent manager to use it.');
            return;
        }
        if (agentHealth.canCreate && typeof this.agent !== 'string') {
            this.canCreate = true;
            if (this.autoInstallAgents) {
                this.createAgent();
                return;
            }
            this.errorMsg = gettext('The agent does not exist. You can create it now.');
            return;
        }
        if (!agentHealth.canCreate) {
            this.errorMsg = gettext('The agent does not exist. Please contact your administrator.');
            if (agentHealth.messages?.length) {
                this.errorMsg += '\n' + agentHealth.messages.join(' ');
            }
            return;
        }
        this.errorMsg = gettext('Unknown error. Please contact your administrator.');
    }
    processAgentMessage(currentAssistantMessage, messageFromAssistant, agentName, message) {
        currentAssistantMessage.content = messageFromAssistant.content;
        const steps = messageFromAssistant.steps || [];
        const lastStep = steps.length ? steps[steps.length - 1] : null;
        this.onMessageDelta.emit(lastStep.textDelta);
        this.onMessageText.emit(lastStep.text);
        currentAssistantMessage.componentSteps$ = of(steps).pipe(this.defaultAgentStepRendererPipe);
        if (messageFromAssistant.finishReason === 'stop') {
            currentAssistantMessage.timestamp = new Date().toISOString();
            this.onMessageFinish.emit(currentAssistantMessage.content);
            this.gainsightService.triggerEvent('ai.agent.message', {
                agent: agentName,
                user: message,
                assistant: currentAssistantMessage.content
            });
            this.isLoading = false;
        }
        if (messageFromAssistant.finishReason === 'error') {
            currentAssistantMessage.timestamp = new Date().toISOString();
            this.isLoading = false;
        }
        if (lastStep?.toolResults) {
            lastStep.toolResults.forEach(toolResult => {
                this.onToolResult.emit(toolResult);
            });
        }
        // as we are mutating the currentAssistantMessage object
        // which is already in the messages array we need to emit a new array reference
        this.messages$.next([...this.messages$.value]);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AgentChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", 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" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: AgentChatComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-agent-chat', imports: [
                        AiChatComponent,
                        AiChatSuggestionComponent,
                        AiChatMessageComponent,
                        AiChatMessageActionComponent,
                        LoadingComponent,
                        MarkdownToHtmlPipe,
                        AsyncPipe,
                        NgComponentOutlet,
                        C8yTranslatePipe,
                        EmptyStateComponent
                    ], 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" }]
        }], propDecorators: { agent: [{
                type: Input,
                args: [{ required: true }]
            }], suggestions: [{
                type: Input
            }], title: [{
                type: Input
            }], headline: [{
                type: Input
            }], welcomeText: [{
                type: Input
            }], autoInstallAgents: [{
                type: Input
            }], variables: [{
                type: Input
            }], stepRenderComponent: [{
                type: Input
            }], onMessageDelta: [{
                type: Output
            }], onMessageText: [{
                type: Output
            }], onMessageFinish: [{
                type: Output
            }], onToolResult: [{
                type: Output
            }] } });

class WidgetAiChatSectionComponent {
    constructor() {
        this.suggestions = [];
        this.headline = gettext('Welcome!');
        this.title = gettext('What can I help you with?');
        this.useContextAsVariable = true;
        this.contextVariableName = 'c8yContext';
        this.widgetConfigService = inject(WidgetConfigService);
        this.alertService = inject(AlertService);
        this.contextRouteService = inject(ContextRouteService);
        /**
         * A component that is used to render each step in the chat. By default, it uses the `AgentStepFeedbackComponent`.
         * You can provide your own component by returning it from this callback.
         *
         * @returns A promise that resolves to a component type.
         */
        this.loadRenderStepComponent = () => Promise.resolve(AgentStepFeedbackComponent);
        /**
         * A callback that is invoked when a tool result is returned. The function can return either:
         * - `undefined` or `void`: No action is taken.
         * - an object which is stored to the widget configuration.
         */
        this.onToolResult = () => undefined;
    }
    /**
     * @ignore
     */
    async ngOnInit() {
        if (!this.variables && this.useContextAsVariable) {
            const { contextData } = this.contextRouteService.activatedContextData;
            this.variables = {
                [this.contextVariableName]: contextData || this.widgetConfigService.currentConfig.device
            };
        }
        this._renderStepComponent = await this.loadRenderStepComponent();
    }
    /**
     * Handles the tool result returned from the AI agent.
     * @param tool The tool result returned from the AI agent.
     */
    toolResultHandler(tool) {
        try {
            const parsedResult = this.onToolResult(tool);
            if (!parsedResult) {
                return;
            }
            this.widgetConfigService.updateConfig({
                config: {
                    ...this.widgetConfigService.currentConfig,
                    ...parsedResult
                }
            }, true);
        }
        catch (e) {
            this.alertService.danger(gettext('There was an error processing the AI response.'));
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetAiChatSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", 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" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetAiChatSectionComponent, decorators: [{
            type: Component,
            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" }]
        }], propDecorators: { suggestions: [{
                type: Input
            }], agent: [{
                type: Input
            }], headline: [{
                type: Input
            }], title: [{
                type: Input
            }], welcomeText: [{
                type: Input
            }], variables: [{
                type: Input
            }], useContextAsVariable: [{
                type: Input
            }], contextVariableName: [{
                type: Input
            }], loadRenderStepComponent: [{
                type: Input
            }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { AgentChatComponent, AgentStepFeedbackComponent, WidgetAiChatSectionComponent };
//# sourceMappingURL=c8y-ngx-components-ai-agent-chat.mjs.map
