maquito-chat-plugin 1.1.4 → 1.1.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.
|
@@ -131,8 +131,9 @@ class IntelligentChatService {
|
|
|
131
131
|
try {
|
|
132
132
|
const parsed = JSON.parse(eventData);
|
|
133
133
|
if (eventType === 'progress') {
|
|
134
|
-
//
|
|
135
|
-
|
|
134
|
+
// Emit progress WITHOUT re-entering Angular zone.
|
|
135
|
+
// The component debounces these via requestAnimationFrame.
|
|
136
|
+
observer.next({ type: 'progress', step: parsed.step, message: parsed.message });
|
|
136
137
|
}
|
|
137
138
|
else if (eventType === 'result') {
|
|
138
139
|
zone.run(() => {
|
|
@@ -208,6 +209,11 @@ class IntelligentChatPluginComponent {
|
|
|
208
209
|
pipelineStep = '';
|
|
209
210
|
messageId = 0;
|
|
210
211
|
shouldScroll = false;
|
|
212
|
+
// ─── Markdown Cache (avoids re-parsing on every CD cycle) ────
|
|
213
|
+
mdCache = new Map();
|
|
214
|
+
// ─── Debounce progress updates to avoid CD storms ────
|
|
215
|
+
pendingPipelineStep = null;
|
|
216
|
+
rafId = null;
|
|
211
217
|
// ─── Session Persistence ──────────────────────────
|
|
212
218
|
STORAGE_PREFIX = 'iq_chat_session_';
|
|
213
219
|
sessionKey = '';
|
|
@@ -396,7 +402,19 @@ class IntelligentChatPluginComponent {
|
|
|
396
402
|
this.currentSubscription = this.chatService.executeIntelligentQueryStream(cfg.apiUrl, cfg.token, cfg.systemId, text, history, ctx, cfg.skipPatterns, cfg.preferTableFormat, cfg.userName || undefined, cfg.personality || undefined).subscribe({
|
|
397
403
|
next: (event) => {
|
|
398
404
|
if (event.type === 'progress') {
|
|
399
|
-
|
|
405
|
+
// Debounce progress updates — queue for next animation frame
|
|
406
|
+
// to avoid triggering Angular CD on every SSE chunk
|
|
407
|
+
this.pendingPipelineStep = event.message || '';
|
|
408
|
+
if (this.rafId === null) {
|
|
409
|
+
this.rafId = requestAnimationFrame(() => {
|
|
410
|
+
this.rafId = null;
|
|
411
|
+
if (this.pendingPipelineStep !== null) {
|
|
412
|
+
this.pipelineStep = this.pendingPipelineStep;
|
|
413
|
+
this.pendingPipelineStep = null;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
return;
|
|
400
418
|
}
|
|
401
419
|
else if (event.type === 'result') {
|
|
402
420
|
this.pipelineStep = '';
|
|
@@ -583,6 +601,10 @@ class IntelligentChatPluginComponent {
|
|
|
583
601
|
renderMarkdown(text) {
|
|
584
602
|
if (!text)
|
|
585
603
|
return '';
|
|
604
|
+
// Return cached result if available (avoids re-parsing on every CD cycle)
|
|
605
|
+
const cached = this.mdCache.get(text);
|
|
606
|
+
if (cached)
|
|
607
|
+
return cached;
|
|
586
608
|
try {
|
|
587
609
|
// Safety valve: if text is extremely long, skip regex-heavy preprocessing
|
|
588
610
|
// to avoid catastrophic backtracking that freezes the browser
|
|
@@ -595,7 +617,9 @@ class IntelligentChatPluginComponent {
|
|
|
595
617
|
// Inject inline styles + onerror on <img> to force small thumbnails & hide broken ones
|
|
596
618
|
const imgStyle = `style="max-height:48px;max-width:100px;object-fit:contain;border-radius:6px;cursor:pointer;display:inline-block;vertical-align:middle;margin:2px 4px;border:1px solid rgba(255,255,255,0.15);box-shadow:0 1px 3px rgba(0,0,0,0.2);"`;
|
|
597
619
|
html = html.replace(/<img /g, `<img ${imgStyle} onerror="this.style.display='none'" `);
|
|
598
|
-
|
|
620
|
+
const result = this.sanitizer.bypassSecurityTrustHtml(html);
|
|
621
|
+
this.mdCache.set(text, result);
|
|
622
|
+
return result;
|
|
599
623
|
}
|
|
600
624
|
catch {
|
|
601
625
|
return text;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maquito-chat-plugin.mjs","sources":["../../../frontend/maquito-chat-plugin/src/lib/intelligent-chat.service.ts","../../../frontend/maquito-chat-plugin/src/lib/intelligent-chat-plugin.component.ts","../../../frontend/maquito-chat-plugin/src/public-api.ts","../../../frontend/maquito-chat-plugin/src/maquito-chat-plugin.ts"],"sourcesContent":["import { Injectable, inject, NgZone } from '@angular/core';\r\nimport { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\n\r\n/**\r\n * Standalone HTTP service for the Maquito Chat Plugin.\r\n * Decoupled from any host app service — uses apiUrl + token from config.\r\n * Replicates exactly the same endpoints used by the Maquito Core API.\r\n *\r\n * IMPORTANT: The SSE streaming method runs OUTSIDE Angular Zone to prevent\r\n * change detection storms that freeze the host application's UI.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class IntelligentChatService {\r\n\r\n private http = inject(HttpClient);\r\n private ngZone = inject(NgZone);\r\n\r\n /**\r\n * Execute an intelligent query (POST /api/query).\r\n * Auth via X-Api-Key header.\r\n */\r\n executeIntelligentQuery(\r\n apiUrl: string,\r\n token: string,\r\n systemId: string,\r\n question: string,\r\n conversationHistory: { role: string; content: string }[] = [],\r\n baseContext?: string,\r\n skipPatternCache?: boolean,\r\n preferTableFormat?: boolean,\r\n userName?: string,\r\n personality?: string\r\n ): Observable<any> {\r\n const headers = this.buildHeaders(token);\r\n const body: any = { systemId, question, conversationHistory };\r\n if (baseContext) body.baseContext = baseContext;\r\n if (skipPatternCache) body.skipPatternCache = skipPatternCache;\r\n if (preferTableFormat !== undefined) body.preferTableFormat = preferTableFormat;\r\n if (userName) body.userName = userName;\r\n if (personality) body.personality = personality;\r\n return this.http.post<any>(`${apiUrl}/query`, body, { headers });\r\n }\r\n\r\n /**\r\n * Execute an intelligent query with SSE streaming progress.\r\n * Emits: { type: 'progress', step: string, message: string }\r\n * { type: 'result', data: any }\r\n *\r\n * The fetch + reader loop runs OUTSIDE Angular Zone to avoid\r\n * triggering change detection on every microtask (which would\r\n * freeze the host app). Emissions re-enter the zone via ngZone.run().\r\n */\r\n executeIntelligentQueryStream(\r\n apiUrl: string,\r\n token: string,\r\n systemId: string,\r\n question: string,\r\n conversationHistory: { role: string; content: string }[] = [],\r\n baseContext?: string,\r\n skipPatternCache?: boolean,\r\n preferTableFormat?: boolean,\r\n userName?: string,\r\n personality?: string\r\n ): Observable<{ type: 'progress' | 'result'; step?: string; message?: string; data?: any }> {\r\n const body: any = { systemId, question, conversationHistory };\r\n if (baseContext) body.baseContext = baseContext;\r\n if (skipPatternCache) body.skipPatternCache = skipPatternCache;\r\n if (preferTableFormat !== undefined) body.preferTableFormat = preferTableFormat;\r\n if (userName) body.userName = userName;\r\n if (personality) body.personality = personality;\r\n\r\n const FETCH_TIMEOUT_MS = 120_000; // 2 min max for the entire request\r\n const INACTIVITY_TIMEOUT_MS = 60_000; // 60s without data = abort\r\n const zone = this.ngZone;\r\n\r\n return new Observable(observer => {\r\n const abortController = new AbortController();\r\n\r\n // Run the entire fetch + SSE loop OUTSIDE Angular Zone\r\n // to prevent change detection storms that freeze the UI\r\n zone.runOutsideAngular(() => {\r\n // Combine user abort + global timeout\r\n let signal: AbortSignal;\r\n if (typeof AbortSignal.any === 'function') {\r\n signal = AbortSignal.any([abortController.signal, AbortSignal.timeout(FETCH_TIMEOUT_MS)]);\r\n } else {\r\n signal = abortController.signal;\r\n setTimeout(() => abortController.abort(), FETCH_TIMEOUT_MS);\r\n }\r\n\r\n fetch(`${apiUrl}/query/stream`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': token },\r\n body: JSON.stringify(body),\r\n signal\r\n }).then(async response => {\r\n if (!response.ok || !response.body) {\r\n zone.run(() => observer.error(new Error(`HTTP ${response.status}`)));\r\n return;\r\n }\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let lastDataTime = Date.now();\r\n\r\n while (true) {\r\n // Race reader vs inactivity timeout\r\n const readPromise = reader.read();\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n const elapsed = Date.now() - lastDataTime;\r\n const remaining = Math.max(INACTIVITY_TIMEOUT_MS - elapsed, 100);\r\n setTimeout(() => reject(new Error('SSE inactivity timeout: no data received for 60s')), remaining);\r\n });\r\n\r\n let result: ReadableStreamReadResult<Uint8Array>;\r\n try {\r\n result = await Promise.race([readPromise, timeoutPromise]);\r\n } catch (err) {\r\n reader.cancel();\r\n abortController.abort();\r\n zone.run(() => observer.error(err));\r\n return;\r\n }\r\n\r\n const { done, value } = result;\r\n if (done) break;\r\n lastDataTime = Date.now();\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n const parts = buffer.split('\\n\\n');\r\n buffer = parts.pop() || '';\r\n for (const part of parts) {\r\n const lines = part.split('\\n');\r\n let eventType = '';\r\n let eventData = '';\r\n for (const line of lines) {\r\n if (line.startsWith('event: ')) eventType = line.slice(7);\r\n else if (line.startsWith('data: ')) eventData = line.slice(6);\r\n }\r\n if (!eventType || !eventData) continue;\r\n try {\r\n const parsed = JSON.parse(eventData);\r\n if (eventType === 'progress') {\r\n // Re-enter zone for UI updates\r\n zone.run(() => observer.next({ type: 'progress', step: parsed.step, message: parsed.message }));\r\n } else if (eventType === 'result') {\r\n zone.run(() => {\r\n observer.next({ type: 'result', data: parsed });\r\n observer.complete();\r\n });\r\n } else if (eventType === 'error') {\r\n zone.run(() => observer.error(parsed));\r\n }\r\n } catch { /* skip malformed JSON */ }\r\n }\r\n }\r\n if (!observer.closed) {\r\n zone.run(() => observer.complete());\r\n }\r\n }).catch(err => {\r\n if (err.name !== 'AbortError') {\r\n zone.run(() => observer.error(err));\r\n }\r\n });\r\n }); // end runOutsideAngular\r\n\r\n return () => abortController.abort();\r\n });\r\n }\r\n\r\n /**\r\n * Standard orchestration ask (POST /api/cortex/ask).\r\n * Used when intelligent query mode is disabled.\r\n */\r\n ask(apiUrl: string, token: string, text: string): Observable<any> {\r\n const headers = this.buildHeaders(token);\r\n return this.http.post<any>(`${apiUrl}/cortex/ask`, { text }, { headers });\r\n }\r\n\r\n private buildHeaders(token: string): HttpHeaders {\r\n return new HttpHeaders({ 'X-Api-Key': token });\r\n }\r\n}\r\n","import {\r\n Component, Input, inject, signal, computed, ViewChild, ElementRef,\r\n AfterViewChecked, OnChanges, OnInit, OnDestroy, SimpleChanges, HostListener\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';\r\nimport { marked } from 'marked';\r\nimport { Subscription } from 'rxjs';\r\nimport { IntelligentChatConfig, ChatMessage, PluginTheme } from './intelligent-chat.models';\r\nimport { IntelligentChatService } from './intelligent-chat.service';\r\n\r\n@Component({\r\n selector: 'intelligent-chat-plugin',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule],\r\n template: `\r\n <!-- Host theme overrides -->\r\n <div class=\"iq-theme-host\" [ngStyle]=\"themeStyles()\">\r\n\r\n <!-- Floating Bubble Button (hidden when expanded) -->\r\n @if (!isExpanded()) {\r\n <button\r\n class=\"iq-bubble\"\r\n [class.iq-bottom-left]=\"resolvedConfig().position === 'bottom-left'\"\r\n [class.iq-open]=\"isOpen()\"\r\n [style.position]=\"resolvedConfig().stickyBubble ? 'fixed' : 'absolute'\"\r\n (click)=\"toggleChat()\"\r\n [attr.aria-label]=\"isOpen() ? 'Cerrar chat' : 'Abrir chat'\"\r\n >\r\n @if (isOpen()) {\r\n <span class=\"iq-bubble-icon\">✕</span>\r\n } @else {\r\n @switch (resolvedConfig().bubbleIconType) {\r\n @case ('image') {\r\n <img [src]=\"resolvedConfig().bubbleImageUrl\" alt=\"Chat\" class=\"iq-bubble-img\" />\r\n }\r\n @case ('svg') {\r\n <span class=\"iq-bubble-svg\" [innerHTML]=\"sanitizedBubbleSvg()\"></span>\r\n }\r\n @default {\r\n <span class=\"iq-bubble-icon\">{{ resolvedConfig().bubbleIcon }}</span>\r\n }\r\n }\r\n }\r\n </button>\r\n }\r\n\r\n <!-- Chat Panel -->\r\n @if (isOpen()) {\r\n <div\r\n class=\"iq-panel\"\r\n [class.iq-bottom-left]=\"resolvedConfig().position === 'bottom-left'\"\r\n [class.iq-expanded]=\"isExpanded()\"\r\n [class]=\"resolvedConfig().themeClass || ''\"\r\n [style.position]=\"resolvedConfig().stickyBubble ? 'fixed' : 'absolute'\"\r\n >\r\n <!-- Header -->\r\n <div class=\"iq-header\">\r\n <span class=\"iq-header-title\">{{ resolvedConfig().title }}</span>\r\n <div class=\"iq-header-actions\">\r\n <button class=\"iq-header-btn\" (click)=\"clearChat()\" title=\"Limpiar chat\">🗑️</button>\r\n @if (resolvedConfig().allowExpand) {\r\n <button class=\"iq-header-btn iq-btn-expand\" (click)=\"toggleExpand()\" [title]=\"isExpanded() ? 'Contraer' : 'Expandir'\">\r\n {{ isExpanded() ? '⊡' : '⛶' }}\r\n </button>\r\n }\r\n <button class=\"iq-header-btn\" (click)=\"isExpanded() ? toggleExpand() : toggleChat()\">✕</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Auth Error Banner -->\r\n @if (authError()) {\r\n <div class=\"iq-auth-error\">\r\n <span>🔒</span>\r\n <span>{{ authError() }}</span>\r\n </div>\r\n }\r\n\r\n <!-- Messages -->\r\n <div class=\"iq-messages\" #chatContainer>\r\n @if (messages().length === 0 && !authError()) {\r\n <div class=\"iq-empty\">\r\n <div class=\"iq-empty-icon\">\r\n @switch (resolvedConfig().bubbleIconType) {\r\n @case ('image') {\r\n <img [src]=\"resolvedConfig().bubbleImageUrl\" alt=\"\" class=\"iq-empty-img\" />\r\n }\r\n @case ('svg') {\r\n <span class=\"iq-empty-svg\" [innerHTML]=\"sanitizedBubbleSvg()\"></span>\r\n }\r\n @default {\r\n <span>{{ resolvedConfig().bubbleIcon }}</span>\r\n }\r\n }\r\n </div>\r\n <p>{{ resolvedConfig().welcomeTitle }}</p>\r\n <p class=\"iq-text-muted\">{{ resolvedConfig().welcomeSubtitle }}</p>\r\n </div>\r\n }\r\n\r\n @for (msg of messages(); track msg.id) {\r\n <div class=\"iq-msg\" [class.iq-msg-user]=\"msg.sender === 'user'\" [class.iq-msg-bot]=\"msg.sender === 'bot'\">\r\n <div class=\"iq-msg-content\">\r\n @if (msg.sender === 'bot') {\r\n <div class=\"iq-md\" [innerHTML]=\"renderMarkdown(msg.text)\" (click)=\"onMessageClick($event)\"></div>\r\n } @else {\r\n <p>{{ msg.text }}</p>\r\n }\r\n <span class=\"iq-msg-time\">{{ formatTime(msg.timestamp) }}</span>\r\n </div>\r\n @if (msg.sender === 'bot' && msg.traceData && resolvedConfig().showTrace) {\r\n <button class=\"iq-btn-trace\" (click)=\"showTrace(msg)\">🔍 Ver Traza</button>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Pipeline progress -->\r\n @if (isLoading()) {\r\n <div class=\"iq-msg iq-msg-bot\">\r\n <div class=\"iq-msg-content iq-pipeline\">\r\n <span class=\"iq-dot\"></span>\r\n <span class=\"iq-pipeline-text\">{{ pipelineStep }}</span>\r\n <button class=\"iq-cancel-btn\" (click)=\"cancelQuery()\" title=\"Cancelar consulta\">✕</button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Input -->\r\n <form class=\"iq-input-bar\" (ngSubmit)=\"sendMessage()\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"inputText\"\r\n name=\"message\"\r\n [placeholder]=\"resolvedConfig().placeholder!\"\r\n [disabled]=\"isLoading() || !!authError()\"\r\n autocomplete=\"off\"\r\n />\r\n <button type=\"submit\" class=\"iq-btn-send\" [disabled]=\"isLoading() || !inputText.trim() || !!authError()\">\r\n ➤\r\n </button>\r\n </form>\r\n </div>\r\n }\r\n\r\n <!-- Trace Modal Overlay -->\r\n @if (selectedTrace()) {\r\n <div class=\"iq-trace-overlay\" (click)=\"closeTrace()\">\r\n <div class=\"iq-trace-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"iq-trace-header\">\r\n <h3>🔍 Detalle de Traza</h3>\r\n <button class=\"iq-header-btn\" (click)=\"closeTrace()\">✕</button>\r\n </div>\r\n <div class=\"iq-trace-body\">\r\n @if (selectedTrace()?.fromCache !== undefined) {\r\n <div class=\"iq-trace-item\">\r\n <label>Origen</label>\r\n <code [class.iq-cache-hit]=\"selectedTrace()?.fromCache\">{{ selectedTrace()?.fromCache ? '📚 Desde Caché' : '🤖 Generado por GPT' }}</code>\r\n </div>\r\n }\r\n @if (selectedTrace()?.query) {\r\n <div class=\"iq-trace-item\">\r\n <label>Query Generada</label>\r\n <pre class=\"iq-query-code\">{{ selectedTrace()?.query }}</pre>\r\n </div>\r\n }\r\n @if (selectedTrace()?.explanation) {\r\n <div class=\"iq-trace-item\">\r\n <label>Explicación</label>\r\n <code>{{ selectedTrace()?.explanation }}</code>\r\n </div>\r\n }\r\n @if (selectedTrace()?.traceId) {\r\n <div class=\"iq-trace-item\">\r\n <label>Trace ID</label>\r\n <code>{{ selectedTrace()?.traceId }}</code>\r\n </div>\r\n }\r\n @if (selectedTrace()?.data) {\r\n <div class=\"iq-trace-item\">\r\n <label>Datos Retornados</label>\r\n <pre>{{ selectedTrace()?.data | json }}</pre>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Link Modal Overlay -->\r\n @if (modalUrl()) {\r\n <div class=\"iq-link-overlay\" (click)=\"closeLinkModal()\">\r\n <div class=\"iq-link-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"iq-link-header\">\r\n @if (showHomeBtn()) {\r\n <button class=\"iq-header-btn iq-back-btn\" (click)=\"iframeGoHome()\" title=\"Volver al inicio\">🏠</button>\r\n }\r\n <span class=\"iq-link-title\" [title]=\"modalUrl()!\">{{ modalUrl() }}</span>\r\n <div class=\"iq-link-actions\">\r\n <a [href]=\"modalUrl()!\" target=\"_blank\" rel=\"noopener\" class=\"iq-header-btn\" title=\"Abrir en nueva pestaña\">↗</a>\r\n <button class=\"iq-header-btn\" (click)=\"closeLinkModal()\">✕</button>\r\n </div>\r\n </div>\r\n <div class=\"iq-iframe-wrapper\">\r\n @if (isModalImage()) {\r\n <img [src]=\"modalUrl()!\" class=\"iq-modal-img\" alt=\"Imagen\" />\r\n } @else {\r\n @if (modalLoading()) {\r\n <div class=\"iq-iframe-loader\">\r\n <div class=\"iq-spinner\"></div>\r\n <span class=\"iq-loader-text\">Cargando...</span>\r\n </div>\r\n }\r\n <iframe #linkIframe [src]=\"sanitizedModalUrl()\" class=\"iq-link-iframe\"\r\n [class.iq-iframe-hidden]=\"modalLoading()\"\r\n (load)=\"onIframeLoaded()\"></iframe>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div><!-- /iq-theme-host -->\r\n `,\r\n styles: [`\r\n /* ========= CSS Custom Properties (overridable by host) ========= */\r\n :host {\r\n --iq-primary: #1a3a5c;\r\n --iq-primary-light: #2a5a8c;\r\n --iq-accent: #00d4aa;\r\n --iq-accent-light: #33e0be;\r\n --iq-bg: #1e1e2f;\r\n --iq-bg-card: #252538;\r\n --iq-bg-tertiary: #35354a;\r\n --iq-text: #ffffff;\r\n --iq-text-secondary: #a0a0b0;\r\n --iq-text-muted: #6c6c7c;\r\n --iq-border: #3a3a4d;\r\n --iq-radius: 12px;\r\n --iq-bubble-size: 56px;\r\n --iq-panel-width: 400px;\r\n --iq-panel-height: 520px;\r\n --iq-z: 10000;\r\n --iq-font: 'Inter', 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif;\r\n font-family: var(--iq-font);\r\n }\r\n\r\n /* ========= Bubble ========= */\r\n .iq-bubble {\r\n position: fixed;\r\n bottom: 24px;\r\n right: 24px;\r\n z-index: var(--iq-z);\r\n width: var(--iq-bubble-size);\r\n height: var(--iq-bubble-size);\r\n border-radius: 50%;\r\n border: none;\r\n background: linear-gradient(135deg, var(--iq-accent), var(--iq-accent-light));\r\n color: var(--iq-bg);\r\n font-size: 1.6rem;\r\n cursor: pointer;\r\n box-shadow: 0 4px 16px rgba(0, 212, 170, 0.4);\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n .iq-bubble:hover {\r\n transform: scale(1.1);\r\n box-shadow: 0 6px 24px rgba(0, 212, 170, 0.5);\r\n }\r\n .iq-bubble .iq-bubble-icon {\r\n font-size: 1.5rem;\r\n pointer-events: none;\r\n }\r\n\r\n .iq-bubble-img {\r\n width: 60%; height: 60%;\r\n object-fit: contain; border-radius: 50%;\r\n pointer-events: none;\r\n }\r\n\r\n .iq-bubble-svg {\r\n width: 60%; height: 60%;\r\n display: flex; align-items: center; justify-content: center;\r\n pointer-events: none;\r\n }\r\n .iq-bubble-svg :deep(svg) { width: 100%; height: 100%; }\r\n\r\n .iq-bubble.iq-open {\r\n background: var(--iq-bg-tertiary);\r\n color: var(--iq-text);\r\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\r\n font-size: 1.2rem;\r\n }\r\n .iq-bubble.iq-bottom-left {\r\n right: auto;\r\n left: 24px;\r\n }\r\n .iq-bubble-icon { line-height: 1; }\r\n\r\n /* ========= Panel ========= */\r\n .iq-panel {\r\n position: fixed;\r\n bottom: 92px;\r\n right: 24px;\r\n z-index: var(--iq-z);\r\n width: var(--iq-panel-width);\r\n height: var(--iq-panel-height);\r\n background: var(--iq-bg);\r\n border: 1px solid var(--iq-border);\r\n border-radius: var(--iq-radius);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n box-shadow: 0 12px 40px rgba(0,0,0,0.5);\r\n animation: iq-slide-up 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n .iq-panel.iq-bottom-left {\r\n right: auto;\r\n left: 24px;\r\n }\r\n /* ========= Expanded / Fullscreen ========= */\r\n .iq-panel.iq-expanded {\r\n width: 100vw !important;\r\n height: 100vh !important;\r\n top: 0 !important;\r\n left: 0 !important;\r\n right: 0 !important;\r\n bottom: 0 !important;\r\n border: none;\r\n border-radius: 0;\r\n overflow: clip;\r\n z-index: calc(var(--iq-z) + 5);\r\n animation: iq-expand 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n .iq-btn-expand {\r\n font-size: 1.1rem !important;\r\n }\r\n @keyframes iq-expand {\r\n from { opacity: 0.8; transform: scale(0.95); }\r\n to { opacity: 1; transform: scale(1); }\r\n }\r\n @keyframes iq-slide-up {\r\n from { opacity: 0; transform: translateY(16px) scale(0.96); }\r\n to { opacity: 1; transform: translateY(0) scale(1); }\r\n }\r\n\r\n /* ========= Header ========= */\r\n .iq-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--iq-border);\r\n background: var(--iq-bg-card);\r\n }\r\n .iq-header-title {\r\n font-weight: 600;\r\n font-size: 0.95rem;\r\n color: var(--iq-text);\r\n }\r\n .iq-header-actions {\r\n display: flex;\r\n gap: 4px;\r\n }\r\n .iq-header-btn {\r\n background: none;\r\n border: none;\r\n color: var(--iq-text-muted);\r\n cursor: pointer;\r\n font-size: 1rem;\r\n padding: 4px 6px;\r\n border-radius: 4px;\r\n transition: all 0.15s;\r\n }\r\n .iq-header-btn:hover {\r\n color: var(--iq-text);\r\n background: rgba(255,255,255,0.08);\r\n }\r\n\r\n /* ========= Auth Error ========= */\r\n .iq-auth-error {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 10px 16px;\r\n background: rgba(220, 53, 69, 0.15);\r\n color: #ff6b7a;\r\n font-size: 0.8rem;\r\n border-bottom: 1px solid rgba(220, 53, 69, 0.25);\r\n }\r\n\r\n /* ========= Messages ========= */\r\n .iq-messages {\r\n flex: 1;\r\n min-height: 0;\r\n overflow-y: auto;\r\n padding: 12px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 10px;\r\n }\r\n\r\n .iq-empty {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n text-align: center;\r\n color: var(--iq-text-secondary);\r\n }\r\n .iq-empty-icon { font-size: 3rem; margin-bottom: 8px; display: flex; align-items: center; justify-content: center; }\r\n .iq-empty-img { width: 48px; height: 48px; object-fit: contain; border-radius: 8px; }\r\n .iq-empty-svg { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; }\r\n .iq-empty-svg :deep(svg) { width: 100%; height: 100%; }\r\n .iq-empty p { font-size: 0.95rem; margin: 2px 0; }\r\n .iq-text-muted { color: var(--iq-text-muted) !important; font-size: 0.8rem !important; }\r\n\r\n .iq-msg { display: flex; flex-direction: column; max-width: 85%; }\r\n .iq-msg-user { align-self: flex-end; }\r\n .iq-msg-bot { align-self: flex-start; max-width: 100%; }\r\n\r\n .iq-msg-user .iq-msg-content {\r\n background: linear-gradient(135deg, var(--iq-primary), var(--iq-primary-light));\r\n border-radius: 12px 12px 0 12px;\r\n }\r\n .iq-msg-bot .iq-msg-content {\r\n background: var(--iq-bg-tertiary);\r\n border-radius: 12px 12px 12px 0;\r\n }\r\n .iq-msg-content {\r\n padding: 10px 14px;\r\n color: var(--iq-text);\r\n font-size: 0.85rem;\r\n line-height: 1.45;\r\n }\r\n .iq-msg-content p { margin: 0; white-space: pre-wrap; }\r\n .iq-msg-time {\r\n display: block;\r\n margin-top: 4px;\r\n font-size: 0.65rem;\r\n color: rgba(255,255,255,0.5);\r\n }\r\n\r\n /* Markdown rendered content */\r\n .iq-md { line-height: 1.5; overflow-x: auto; max-width: 100%; }\r\n .iq-md :first-child { margin-top: 0; }\r\n .iq-md :last-child { margin-bottom: 0; }\r\n .iq-md p { margin: 0 0 0.4em 0; }\r\n .iq-md p:last-child { margin-bottom: 0; }\r\n .iq-md strong { color: var(--iq-accent); }\r\n .iq-md ul, .iq-md ol { margin: 0.3em 0; padding-left: 1.2em; }\r\n .iq-md li { margin: 0.15em 0; }\r\n .iq-md code {\r\n background: rgba(0,0,0,0.3);\r\n padding: 0.15em 0.4em;\r\n border-radius: 3px;\r\n font-size: 0.82em;\r\n }\r\n .iq-md pre {\r\n background: rgba(0,0,0,0.3);\r\n padding: 0.8em;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n font-size: 0.78em;\r\n margin: 0.4em 0;\r\n }\r\n .iq-md pre code { background: none; padding: 0; }\r\n .iq-md table {\r\n width: max-content; min-width: 100%;\r\n border-collapse: separate; border-spacing: 0;\r\n margin: 0.5em 0; font-size: 0.75rem;\r\n border-radius: 6px; overflow: hidden;\r\n }\r\n .iq-md thead th {\r\n background: rgba(99,102,241,0.18); color: #a5b4fc;\r\n font-weight: 600; text-align: left;\r\n padding: 0.5em 0.8em; border-bottom: 2px solid rgba(99,102,241,0.3);\r\n white-space: nowrap; font-size: 0.7rem;\r\n text-transform: uppercase; letter-spacing: 0.05em;\r\n }\r\n .iq-md tbody td {\r\n padding: 0.4em 0.8em; border-bottom: 1px solid rgba(255,255,255,0.06);\r\n white-space: nowrap; color: var(--iq-text-secondary);\r\n }\r\n .iq-md tbody tr:hover { background: rgba(99,102,241,0.08); }\r\n\r\n /* Inline images in bot messages – small thumbnails, click to enlarge */\r\n .iq-md img {\r\n max-height: 80px; max-width: 120px; object-fit: cover;\r\n border-radius: 8px; margin: 6px 4px 6px 0;\r\n display: inline-block; vertical-align: middle;\r\n border: 1px solid rgba(255,255,255,0.15);\r\n box-shadow: 0 1px 4px rgba(0,0,0,0.25);\r\n cursor: pointer; transition: transform 0.15s, box-shadow 0.15s;\r\n }\r\n .iq-md img:hover {\r\n transform: scale(1.05);\r\n box-shadow: 0 3px 12px rgba(99,102,241,0.35);\r\n border-color: var(--iq-accent);\r\n }\r\n .iq-md img[alt*=\"logo\"], .iq-md img[alt*=\"marca\"] {\r\n max-height: 28px; max-width: 90px; object-fit: contain;\r\n border: none; box-shadow: none; border-radius: 4px;\r\n background: rgba(255,255,255,0.9); padding: 2px 6px;\r\n }\r\n /* Trace button */\r\n .iq-btn-trace {\r\n align-self: flex-start; margin-top: 4px;\r\n background: transparent; border: 1px solid var(--iq-border);\r\n color: var(--iq-text-secondary); font-size: 0.7rem;\r\n padding: 3px 8px; border-radius: 4px; cursor: pointer;\r\n transition: all 0.15s;\r\n }\r\n .iq-btn-trace:hover { border-color: var(--iq-accent); color: var(--iq-accent); }\r\n\r\n /* Pipeline loading indicator */\r\n .iq-pipeline {\r\n display: flex; align-items: center; gap: 8px;\r\n animation: iq-fade-in 0.3s ease-out;\r\n }\r\n .iq-dot {\r\n width: 8px; height: 8px; border-radius: 50%;\r\n background: var(--iq-accent);\r\n animation: iq-pulse 1s ease-in-out infinite;\r\n }\r\n .iq-pipeline-text {\r\n font-size: 0.8rem; color: var(--iq-text-muted); font-style: italic;\r\n flex: 1;\r\n }\r\n .iq-cancel-btn {\r\n background: transparent; border: 1px solid var(--iq-border);\r\n color: var(--iq-text-muted); font-size: 0.7rem;\r\n padding: 2px 8px; border-radius: 4px; cursor: pointer;\r\n transition: all 0.15s; flex-shrink: 0;\r\n }\r\n .iq-cancel-btn:hover {\r\n border-color: #ff6b6b; color: #ff6b6b; background: rgba(255, 107, 107, 0.1);\r\n }\r\n @keyframes iq-pulse {\r\n 0%, 100% { opacity: 1; transform: scale(1); }\r\n 50% { opacity: 0.4; transform: scale(0.7); }\r\n }\r\n @keyframes iq-fade-in {\r\n from { opacity: 0; transform: translateX(-6px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n }\r\n\r\n /* ========= Input Bar ========= */\r\n .iq-input-bar {\r\n display: flex; gap: 8px;\r\n padding: 10px 12px;\r\n border-top: 1px solid var(--iq-border);\r\n background: var(--iq-bg-card);\r\n }\r\n .iq-input-bar input {\r\n flex: 1; padding: 8px 12px;\r\n background: var(--iq-bg-tertiary);\r\n border: 1px solid var(--iq-border);\r\n border-radius: 8px;\r\n color: var(--iq-text);\r\n font-size: 0.85rem;\r\n font-family: var(--iq-font);\r\n outline: none;\r\n transition: border-color 0.15s;\r\n }\r\n .iq-input-bar input:focus { border-color: var(--iq-accent); }\r\n .iq-input-bar input::placeholder { color: var(--iq-text-muted); }\r\n .iq-input-bar input:disabled { opacity: 0.5; }\r\n .iq-btn-send {\r\n width: 36px; height: 36px;\r\n border-radius: 8px; border: none;\r\n background: linear-gradient(135deg, var(--iq-accent), var(--iq-accent-light));\r\n color: var(--iq-bg); font-size: 1rem;\r\n cursor: pointer; transition: all 0.2s;\r\n display: flex; align-items: center; justify-content: center;\r\n }\r\n .iq-btn-send:hover:not(:disabled) { box-shadow: 0 0 12px rgba(0,212,170,0.4); transform: translateY(-1px); }\r\n .iq-btn-send:disabled { opacity: 0.4; cursor: not-allowed; }\r\n\r\n /* ========= Trace Modal ========= */\r\n .iq-trace-overlay {\r\n position: fixed; inset: 0;\r\n z-index: calc(var(--iq-z) + 10);\r\n background: rgba(0,0,0,0.6);\r\n display: flex; align-items: center; justify-content: center;\r\n animation: iq-fade-in 0.2s ease-out;\r\n }\r\n .iq-trace-modal {\r\n width: 90%; max-width: 520px; max-height: 80vh;\r\n background: var(--iq-bg); border: 1px solid var(--iq-border);\r\n border-radius: var(--iq-radius);\r\n display: flex; flex-direction: column; overflow: hidden;\r\n box-shadow: 0 20px 50px rgba(0,0,0,0.6);\r\n }\r\n .iq-trace-header {\r\n display: flex; align-items: center; justify-content: space-between;\r\n padding: 14px 16px; border-bottom: 1px solid var(--iq-border);\r\n }\r\n .iq-trace-header h3 { margin: 0; font-size: 0.95rem; color: var(--iq-text); }\r\n .iq-trace-body {\r\n flex: 1; overflow-y: auto; padding: 16px;\r\n display: flex; flex-direction: column; gap: 12px;\r\n }\r\n .iq-trace-item label {\r\n display: block; font-size: 0.7rem; color: var(--iq-text-muted);\r\n margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.05em;\r\n }\r\n .iq-trace-item code {\r\n display: block; padding: 8px;\r\n background: var(--iq-bg-tertiary); border-radius: 4px;\r\n font-family: monospace; font-size: 0.8rem; color: var(--iq-accent);\r\n word-break: break-all;\r\n }\r\n .iq-trace-item pre {\r\n margin: 0; padding: 8px;\r\n background: var(--iq-bg-tertiary); border-radius: 4px;\r\n font-family: monospace; font-size: 0.7rem;\r\n overflow-x: auto; max-height: 180px; color: var(--iq-text-secondary);\r\n }\r\n .iq-cache-hit { background: rgba(16,185,129,0.15) !important; color: #10b981 !important; }\r\n .iq-query-code { color: var(--iq-accent) !important; }\r\n\r\n /* ========= Link Modal ========= */\r\n .iq-link-overlay {\r\n position: fixed; inset: 0;\r\n z-index: calc(var(--iq-z) + 20);\r\n background: rgba(0,0,0,0.7);\r\n display: flex; align-items: center; justify-content: center;\r\n animation: iq-fade-in 0.2s ease-out;\r\n backdrop-filter: blur(4px);\r\n }\r\n .iq-link-modal {\r\n width: 94vw; height: 92vh;\r\n background: var(--iq-bg); border: 1px solid var(--iq-border);\r\n border-radius: var(--iq-radius);\r\n display: flex; flex-direction: column; overflow: hidden;\r\n box-shadow: 0 24px 60px rgba(0,0,0,0.7);\r\n animation: iq-expand 0.25s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n .iq-link-header {\r\n display: flex; align-items: center; justify-content: space-between;\r\n padding: 10px 16px; border-bottom: 1px solid var(--iq-border);\r\n background: var(--iq-bg-card); gap: 12px; min-height: 44px;\r\n }\r\n .iq-link-title {\r\n flex: 1; font-size: 0.78rem; color: var(--iq-text-secondary);\r\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\r\n font-family: monospace;\r\n }\r\n .iq-link-actions {\r\n display: flex; gap: 4px; flex-shrink: 0;\r\n }\r\n .iq-link-actions a {\r\n text-decoration: none;\r\n }\r\n .iq-back-btn {\r\n flex-shrink: 0; font-size: 1.1rem;\r\n transition: transform 0.15s ease;\r\n }\r\n .iq-back-btn:hover {\r\n transform: translateX(-2px);\r\n }\r\n .iq-iframe-wrapper {\r\n flex: 1; position: relative; overflow: hidden;\r\n }\r\n .iq-link-iframe {\r\n width: 100%; height: 100%; border: none;\r\n background: #fff;\r\n transition: opacity 0.3s ease;\r\n }\r\n .iq-iframe-hidden {\r\n opacity: 0;\r\n }\r\n .iq-modal-img {\r\n width: 100%; height: 100%;\r\n object-fit: contain;\r\n background: #1a1a2e;\r\n }\r\n .iq-iframe-loader {\r\n position: absolute; inset: 0;\r\n display: flex; flex-direction: column;\r\n align-items: center; justify-content: center;\r\n background: var(--iq-bg);\r\n gap: 16px; z-index: 2;\r\n }\r\n .iq-spinner {\r\n width: 40px; height: 40px;\r\n border: 3px solid var(--iq-border);\r\n border-top-color: var(--iq-accent);\r\n border-radius: 50%;\r\n animation: iq-spin 0.8s linear infinite;\r\n }\r\n .iq-loader-text {\r\n font-size: 0.85rem; color: var(--iq-text-secondary);\r\n font-weight: 500;\r\n }\r\n @keyframes iq-spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n\r\n /* ========= Link Modal — markdown link styling ========= */\r\n .iq-md a {\r\n color: var(--iq-accent); text-decoration: underline;\r\n cursor: pointer; transition: color 0.15s;\r\n }\r\n .iq-md a:hover {\r\n color: var(--iq-accent-light);\r\n }\r\n\r\n @media (max-width: 480px) {\r\n .iq-link-modal {\r\n width: 100vw; height: 100dvh;\r\n border-radius: 0;\r\n }\r\n .iq-link-header { padding: 8px 12px; }\r\n .iq-link-title { font-size: 0.7rem; }\r\n }\r\n\r\n /* ========= Scrollbar ========= */\r\n .iq-messages::-webkit-scrollbar { width: 5px; }\r\n .iq-messages::-webkit-scrollbar-track { background: transparent; }\r\n .iq-messages::-webkit-scrollbar-thumb { background: var(--iq-border); border-radius: 4px; }\r\n .iq-trace-body::-webkit-scrollbar { width: 5px; }\r\n .iq-trace-body::-webkit-scrollbar-track { background: transparent; }\r\n .iq-trace-body::-webkit-scrollbar-thumb { background: var(--iq-border); border-radius: 4px; }\r\n /* Wider scrollbar in fullscreen for easier grabbing */\r\n .iq-expanded .iq-messages::-webkit-scrollbar { width: 8px; }\r\n .iq-expanded .iq-messages { scrollbar-gutter: stable; }\r\n\r\n /* ========= Mobile Small Screens ========= */\r\n @media (max-width: 480px) {\r\n .iq-bubble {\r\n bottom: 16px;\r\n right: 16px;\r\n width: 48px;\r\n height: 48px;\r\n font-size: 1.3rem;\r\n }\r\n .iq-bubble.iq-bottom-left {\r\n left: 16px;\r\n }\r\n .iq-bubble .iq-bubble-icon { font-size: 1.2rem; }\r\n\r\n .iq-panel {\r\n right: 8px;\r\n left: 8px;\r\n bottom: 72px;\r\n width: auto !important;\r\n max-width: calc(100vw - 16px);\r\n height: calc(100dvh - 90px);\r\n max-height: calc(100dvh - 90px);\r\n }\r\n .iq-panel.iq-bottom-left {\r\n left: 8px;\r\n right: 8px;\r\n }\r\n .iq-panel.iq-expanded {\r\n top: 0 !important;\r\n left: 0 !important;\r\n right: 0 !important;\r\n bottom: 0 !important;\r\n width: 100vw !important;\r\n height: 100dvh !important;\r\n max-height: 100dvh !important;\r\n max-width: 100vw !important;\r\n border-radius: 0;\r\n }\r\n\r\n .iq-header {\r\n padding: 10px 12px;\r\n }\r\n .iq-header-title { font-size: 0.85rem; }\r\n .iq-header-btn { padding: 6px 8px; min-width: 32px; min-height: 32px; }\r\n\r\n .iq-messages { padding: 8px; gap: 8px; }\r\n\r\n .iq-msg { max-width: 92%; }\r\n .iq-msg-bot { max-width: 100%; }\r\n .iq-msg-content { padding: 8px 10px; font-size: 0.8rem; }\r\n\r\n .iq-md { overflow-x: auto; -webkit-overflow-scrolling: touch; }\r\n .iq-md table { font-size: 0.65rem; min-width: unset; }\r\n .iq-md thead th { padding: 0.35em 0.5em; font-size: 0.6rem; }\r\n .iq-md tbody td { padding: 0.3em 0.5em; font-size: 0.65rem; }\r\n\r\n .iq-empty-icon { font-size: 2.5rem; }\r\n .iq-empty p { font-size: 0.85rem; }\r\n\r\n .iq-input-bar { padding: 8px 10px; gap: 6px; }\r\n .iq-input-bar input { font-size: 16px; padding: 8px 10px; }\r\n .iq-btn-send { width: 38px; height: 38px; flex-shrink: 0; }\r\n\r\n .iq-trace-modal {\r\n width: calc(100vw - 24px);\r\n max-height: 90dvh;\r\n }\r\n .iq-trace-header { padding: 12px; }\r\n .iq-trace-header h3 { font-size: 0.85rem; }\r\n .iq-trace-body { padding: 12px; }\r\n .iq-trace-item pre { font-size: 0.65rem; max-height: 140px; }\r\n }\r\n\r\n /* ========= Landscape Mobile — fit floating panel ========= */\r\n @media (max-height: 500px) and (orientation: landscape) {\r\n .iq-bubble {\r\n bottom: 8px;\r\n right: 8px;\r\n width: 44px;\r\n height: 44px;\r\n font-size: 1.1rem;\r\n }\r\n .iq-bubble.iq-bottom-left { left: 8px; }\r\n\r\n .iq-panel {\r\n right: 60px;\r\n left: 8px;\r\n bottom: 8px;\r\n top: 8px;\r\n width: auto !important;\r\n max-width: calc(100vw - 76px);\r\n height: auto !important;\r\n max-height: calc(100dvh - 16px);\r\n border-radius: var(--iq-radius);\r\n }\r\n .iq-panel.iq-bottom-left {\r\n left: 60px;\r\n right: 8px;\r\n }\r\n .iq-panel.iq-expanded {\r\n top: 0 !important;\r\n left: 0 !important;\r\n right: 0 !important;\r\n bottom: 0 !important;\r\n width: 100vw !important;\r\n height: 100dvh !important;\r\n max-height: 100dvh !important;\r\n max-width: 100vw !important;\r\n border-radius: 0;\r\n }\r\n\r\n .iq-header { padding: 6px 12px; }\r\n .iq-header-title { font-size: 0.8rem; }\r\n .iq-messages { padding: 6px 10px; gap: 6px; }\r\n .iq-empty-icon { font-size: 1.8rem; margin-bottom: 4px; }\r\n .iq-empty p { font-size: 0.78rem; margin: 1px 0; }\r\n .iq-input-bar { padding: 6px 10px; }\r\n .iq-input-bar input { font-size: 16px; padding: 6px 10px; }\r\n .iq-btn-send { width: 32px; height: 32px; }\r\n }\r\n `]\r\n})\r\nexport class IntelligentChatPluginComponent implements AfterViewChecked, OnChanges, OnInit, OnDestroy {\r\n @ViewChild('chatContainer') private chatContainer!: ElementRef;\r\n\r\n @Input() config!: IntelligentChatConfig;\r\n\r\n private chatService = inject(IntelligentChatService);\r\n private hostEl = inject(ElementRef);\r\n\r\n // State\r\n isOpen = signal(false);\r\n isExpanded = signal(false);\r\n messages = signal<ChatMessage[]>([]);\r\n isLoading = signal(false);\r\n selectedTrace = signal<any>(null);\r\n authError = signal<string | null>(null);\r\n modalUrl = signal<string | null>(null);\r\n isModalImage = computed(() => {\r\n const url = this.modalUrl();\r\n if (!url) return false;\r\n return /\\.(jpg|jpeg|png|gif|webp|svg|bmp)(\\?.*)?$/i.test(url);\r\n });\r\n modalLoading = signal(false);\r\n showHomeBtn = signal(false);\r\n private originalModalUrl = '';\r\n private modalReadyForNav = false;\r\n private navReadyTimer: any = null;\r\n inputText = '';\r\n private currentSubscription?: Subscription;\r\n\r\n // Pipeline step (driven by real SSE events from backend)\r\n pipelineStep = '';\r\n\r\n private messageId = 0;\r\n private shouldScroll = false;\r\n\r\n // ─── Session Persistence ──────────────────────────\r\n private readonly STORAGE_PREFIX = 'iq_chat_session_';\r\n private sessionKey = '';\r\n private storageListener = (e: StorageEvent) => this.onStorageChange(e);\r\n\r\n /** Resolved config with defaults applied */\r\n private sanitizer = inject(DomSanitizer);\r\n\r\n resolvedConfig = signal<Required<IntelligentChatConfig>>({\r\n apiUrl: '',\r\n systemId: '',\r\n token: '',\r\n useIntelligentQuery: true,\r\n skipPatterns: true,\r\n baseContext: '',\r\n showTrace: false,\r\n showPipelineSteps: true,\r\n preferTableFormat: true,\r\n title: 'Maquito Chat',\r\n placeholder: 'Escribe tu consulta aquí...',\r\n welcomeTitle: '¡Hola! Soy Maquito.',\r\n welcomeSubtitle: 'Escribe tu consulta para comenzar.',\r\n position: 'bottom-right',\r\n bubbleIcon: '🤖',\r\n bubbleIconType: 'emoji',\r\n bubbleImageUrl: '',\r\n bubbleSvg: '',\r\n themeClass: '',\r\n stickyBubble: true,\r\n allowExpand: false,\r\n theme: {},\r\n userName: '',\r\n personality: ''\r\n });\r\n\r\n /** Map theme object → CSS variable overrides */\r\n themeStyles = computed(() => {\r\n const t = this.resolvedConfig().theme || {};\r\n const map: Record<string, string> = {};\r\n const pairs: [keyof PluginTheme, string][] = [\r\n ['primary', '--iq-primary'], ['primaryLight', '--iq-primary-light'],\r\n ['accent', '--iq-accent'], ['accentLight', '--iq-accent-light'],\r\n ['bg', '--iq-bg'], ['bgCard', '--iq-bg-card'], ['bgTertiary', '--iq-bg-tertiary'],\r\n ['text', '--iq-text'], ['textSecondary', '--iq-text-secondary'],\r\n ['textMuted', '--iq-text-muted'], ['border', '--iq-border']\r\n ];\r\n for (const [key, cssVar] of pairs) {\r\n if (t[key]) map[cssVar] = t[key]!;\r\n }\r\n return map;\r\n });\r\n\r\n /** Sanitised SVG HTML for bubble */\r\n sanitizedBubbleSvg = computed<SafeHtml>(() => {\r\n const raw = this.resolvedConfig().bubbleSvg || '';\r\n return this.sanitizer.bypassSecurityTrustHtml(raw);\r\n });\r\n\r\n /** Sanitised URL for the link modal iframe */\r\n sanitizedModalUrl = computed<SafeResourceUrl>(() => {\r\n const url = this.modalUrl() || '';\r\n return this.sanitizer.bypassSecurityTrustResourceUrl(url);\r\n });\r\n\r\n ngOnInit(): void {\r\n window.addEventListener('storage', this.storageListener);\r\n // Self-heal: always reset transient state on init to prevent\r\n // corrupted sessions from freezing the page\r\n this.isLoading.set(false);\r\n this.pipelineStep = '';\r\n this.isExpanded.set(false);\r\n this.setHostScrollLock(false);\r\n this.currentSubscription?.unsubscribe();\r\n this.currentSubscription = undefined;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n window.removeEventListener('storage', this.storageListener);\r\n this.cancelQuery();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['config'] && this.config) {\r\n this.resolvedConfig.set({\r\n apiUrl: this.config.apiUrl || '',\r\n systemId: this.config.systemId || '',\r\n token: this.config.token || '',\r\n useIntelligentQuery: this.config.useIntelligentQuery ?? true,\r\n skipPatterns: this.config.skipPatterns ?? true,\r\n baseContext: this.config.baseContext || '',\r\n showTrace: this.config.showTrace ?? false,\r\n showPipelineSteps: this.config.showPipelineSteps ?? true,\r\n preferTableFormat: this.config.preferTableFormat ?? true,\r\n title: this.config.title || 'Maquito Chat',\r\n placeholder: this.config.placeholder || 'Escribe tu consulta aquí...',\r\n welcomeTitle: this.config.welcomeTitle || '¡Hola! Soy Maquito.',\r\n welcomeSubtitle: this.config.welcomeSubtitle || 'Escribe tu consulta para comenzar.',\r\n position: this.config.position || 'bottom-right',\r\n bubbleIcon: this.config.bubbleIcon || '🤖',\r\n bubbleIconType: this.config.bubbleIconType || 'emoji',\r\n bubbleImageUrl: this.config.bubbleImageUrl || '',\r\n bubbleSvg: this.config.bubbleSvg || '',\r\n themeClass: this.config.themeClass || '',\r\n stickyBubble: this.config.stickyBubble ?? true,\r\n allowExpand: this.config.allowExpand ?? false,\r\n theme: this.config.theme || {},\r\n userName: this.config.userName || '',\r\n personality: this.config.personality || ''\r\n });\r\n // Cancel any in-flight query when config changes\r\n this.cancelQuery();\r\n // Rebuild session key when config changes\r\n const newKey = this.buildSessionKey();\r\n if (newKey !== this.sessionKey) {\r\n this.sessionKey = newKey;\r\n this.loadSession();\r\n }\r\n // Clear auth error when config changes (user may be testing a new token)\r\n this.authError.set(null);\r\n }\r\n }\r\n\r\n ngAfterViewChecked(): void {\r\n if (this.shouldScroll) {\r\n this.scrollToBottom();\r\n this.shouldScroll = false;\r\n }\r\n }\r\n\r\n toggleChat(): void {\r\n this.isOpen.update(v => !v);\r\n if (!this.isOpen()) {\r\n this.isExpanded.set(false);\r\n this.setHostScrollLock(false);\r\n this.cancelQuery();\r\n }\r\n if (this.isOpen()) this.shouldScroll = true;\r\n }\r\n\r\n toggleExpand(): void {\r\n this.isExpanded.update(v => !v);\r\n this.setHostScrollLock(this.isExpanded());\r\n }\r\n\r\n /** Lock/unlock the host page scroll to prevent its scrollbar from overlapping ours */\r\n private setHostScrollLock(lock: boolean): void {\r\n document.body.style.overflow = lock ? 'hidden' : '';\r\n // Also target common host containers\r\n const mc = document.querySelector('.main-container') as HTMLElement;\r\n if (mc) mc.style.overflow = lock ? 'hidden' : '';\r\n }\r\n\r\n sendMessage(): void {\r\n const text = this.inputText.trim();\r\n if (!text) return;\r\n\r\n const cfg = this.resolvedConfig();\r\n\r\n // Validate required config\r\n if (!cfg.token) {\r\n this.authError.set('Token no configurado. El plugin requiere un token técnico válido.');\r\n return;\r\n }\r\n if (!cfg.apiUrl) {\r\n this.authError.set('API URL no configurada.');\r\n return;\r\n }\r\n\r\n this.authError.set(null);\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text,\r\n sender: 'user',\r\n timestamp: new Date()\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n this.inputText = '';\r\n this.isLoading.set(true);\r\n\r\n if (cfg.showPipelineSteps) {\r\n this.pipelineStep = '⏳ Procesando...';\r\n } else {\r\n this.pipelineStep = '⏳ Procesando...';\r\n }\r\n\r\n if (cfg.useIntelligentQuery && cfg.systemId) {\r\n // Build conversation history from previous messages (last 6 pairs)\r\n const history = this.messages()\r\n .filter(m => m.sender === 'user' || m.sender === 'bot')\r\n .slice(-12)\r\n .map(msg => ({\r\n role: msg.sender === 'user' ? 'user' : 'assistant',\r\n content: msg.text\r\n }));\r\n\r\n const ctx = cfg.baseContext?.trim() || undefined;\r\n\r\n if (cfg.showPipelineSteps) {\r\n // Use SSE streaming for real-time pipeline progress\r\n this.currentSubscription = this.chatService.executeIntelligentQueryStream(\r\n cfg.apiUrl, cfg.token, cfg.systemId, text, history, ctx, cfg.skipPatterns, cfg.preferTableFormat,\r\n cfg.userName || undefined, cfg.personality || undefined\r\n ).subscribe({\r\n next: (event) => {\r\n if (event.type === 'progress') {\r\n this.pipelineStep = event.message || '';\r\n } else if (event.type === 'result') {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n const response = event.data;\r\n const responseText = response.success\r\n ? (response.response || 'Consulta ejecutada correctamente')\r\n : (response.error || 'Error en la consulta');\r\n\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: responseText,\r\n sender: 'bot',\r\n timestamp: new Date(),\r\n traceData: {\r\n traceId: response.traceId,\r\n fromCache: response.fromCache,\r\n fromContext: response.fromContext,\r\n query: response.query,\r\n explanation: response.explanation,\r\n patternId: response.patternId,\r\n data: response.data\r\n }\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n }\r\n },\r\n error: (error) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.setHostScrollLock(false);\r\n this.handleError(error);\r\n }\r\n });\r\n } else {\r\n // Fallback: use standard non-streaming endpoint\r\n this.currentSubscription = this.chatService.executeIntelligentQuery(\r\n cfg.apiUrl, cfg.token, cfg.systemId, text, history, ctx, cfg.skipPatterns, cfg.preferTableFormat,\r\n cfg.userName || undefined, cfg.personality || undefined\r\n ).subscribe({\r\n next: (response: any) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n const responseText = response.success\r\n ? (response.response || 'Consulta ejecutada correctamente')\r\n : (response.error || 'Error en la consulta');\r\n\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: responseText,\r\n sender: 'bot',\r\n timestamp: new Date(),\r\n traceData: {\r\n traceId: response.traceId,\r\n fromCache: response.fromCache,\r\n fromContext: response.fromContext,\r\n query: response.query,\r\n explanation: response.explanation,\r\n patternId: response.patternId,\r\n data: response.data\r\n }\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n },\r\n error: (error) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.setHostScrollLock(false);\r\n this.handleError(error);\r\n }\r\n });\r\n }\r\n } else {\r\n // Standard orchestration (non-intelligent)\r\n this.currentSubscription = this.chatService.ask(cfg.apiUrl, cfg.token, text).subscribe({\r\n next: (response) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: response.data?.response || 'Sin respuesta',\r\n sender: 'bot',\r\n timestamp: new Date(),\r\n traceData: {\r\n traceId: response.traceId,\r\n responseTime: response.data?.processingTime,\r\n appliedRules: response.data?.appliedRules,\r\n decisions: response.data?.decisions\r\n }\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n },\r\n error: (error) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.setHostScrollLock(false);\r\n this.handleError(error);\r\n }\r\n });\r\n }\r\n }\r\n\r\n cancelQuery(): void {\r\n this.currentSubscription?.unsubscribe();\r\n this.currentSubscription = undefined;\r\n this.isLoading.set(false);\r\n this.pipelineStep = '';\r\n this.setHostScrollLock(false);\r\n }\r\n\r\n clearChat(): void {\r\n this.messages.set([]);\r\n this.selectedTrace.set(null);\r\n this.authError.set(null);\r\n this.clearSession();\r\n }\r\n\r\n showTrace(msg: ChatMessage): void {\r\n this.selectedTrace.set(msg.traceData);\r\n }\r\n\r\n closeTrace(): void {\r\n this.selectedTrace.set(null);\r\n }\r\n\r\n // ─── Link Modal ────────────────────────────────\r\n openLinkModal(url: string): void {\r\n this.modalLoading.set(true);\r\n this.showHomeBtn.set(false);\r\n this.modalReadyForNav = false;\r\n clearTimeout(this.navReadyTimer);\r\n this.originalModalUrl = url;\r\n this.modalUrl.set(url);\r\n }\r\n\r\n closeLinkModal(): void {\r\n this.modalUrl.set(null);\r\n this.modalLoading.set(false);\r\n this.showHomeBtn.set(false);\r\n this.modalReadyForNav = false;\r\n clearTimeout(this.navReadyTimer);\r\n this.originalModalUrl = '';\r\n }\r\n\r\n onIframeLoaded(): void {\r\n this.modalLoading.set(false);\r\n if (this.modalReadyForNav) {\r\n // A load AFTER the initial page settled = real navigation\r\n this.showHomeBtn.set(true);\r\n } else {\r\n // Initial page load (may fire multiple times for SPAs/redirects)\r\n // Wait 1s of stability before treating next loads as navigation\r\n clearTimeout(this.navReadyTimer);\r\n this.navReadyTimer = setTimeout(() => { this.modalReadyForNav = true; }, 1000);\r\n }\r\n }\r\n\r\n iframeGoHome(): void {\r\n const iframe = this.hostEl.nativeElement.querySelector('.iq-link-iframe') as HTMLIFrameElement;\r\n if (iframe && this.originalModalUrl) {\r\n this.modalLoading.set(true);\r\n this.showHomeBtn.set(false);\r\n this.modalReadyForNav = false;\r\n clearTimeout(this.navReadyTimer);\r\n iframe.src = this.originalModalUrl;\r\n }\r\n }\r\n\r\n /** Intercept clicks on <a> and <img> tags inside rendered markdown */\r\n onMessageClick(event: MouseEvent): void {\r\n const target = event.target as HTMLElement;\r\n\r\n // Clicking an image opens it full-size in the modal\r\n if (target.tagName === 'IMG') {\r\n const src = (target as HTMLImageElement).src;\r\n if (src) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.openLinkModal(src);\r\n return;\r\n }\r\n }\r\n\r\n const anchor = target.closest('a') as HTMLAnchorElement | null;\r\n if (anchor && anchor.href) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.openLinkModal(anchor.href);\r\n }\r\n }\r\n\r\n formatTime(date: Date): string {\r\n return date.toLocaleTimeString('es-CL', { hour: '2-digit', minute: '2-digit' });\r\n }\r\n\r\n renderMarkdown(text: string): SafeHtml {\r\n if (!text) return '';\r\n try {\r\n // Safety valve: if text is extremely long, skip regex-heavy preprocessing\r\n // to avoid catastrophic backtracking that freezes the browser\r\n let preprocessed = text.length < 100_000 ? this.preprocessMarkdownTable(text) : text;\r\n // Encode spaces in markdown image & link URLs:  and [text](url)\r\n if (preprocessed.length < 100_000) {\r\n preprocessed = preprocessed.replace(\r\n /(!?\\[[^\\]]*\\])\\(([^)]+)\\)/g,\r\n (_match: string, bracket: string, url: string) => `${bracket}(${url.replace(/ /g, '%20')})`\r\n );\r\n }\r\n let html = marked.parse(preprocessed, { breaks: true }) as string;\r\n // Inject inline styles + onerror on <img> to force small thumbnails & hide broken ones\r\n const imgStyle = `style=\"max-height:48px;max-width:100px;object-fit:contain;border-radius:6px;cursor:pointer;display:inline-block;vertical-align:middle;margin:2px 4px;border:1px solid rgba(255,255,255,0.15);box-shadow:0 1px 3px rgba(0,0,0,0.2);\"`;\r\n html = html.replace(/<img /g, `<img ${imgStyle} onerror=\"this.style.display='none'\" `);\r\n return this.sanitizer.bypassSecurityTrustHtml(html);\r\n } catch {\r\n return text;\r\n }\r\n }\r\n\r\n /**\r\n * Pre-process text to ensure pipe-delimited tables render as HTML tables.\r\n *\r\n * The API often returns header + separator + data on ONE line, e.g.:\r\n * \"| Col1 | Col2 | |---|---| | Val1 | Val2 |\"\r\n *\r\n * Step 1: Find the dash-separator pattern (|---|---|) and break the line\r\n * around it so each part (header / separator / data rows) is its\r\n * own line.\r\n * Step 2: Line-by-line cleanup — ensure a blank line exists before the\r\n * first pipe-row and inject a separator if one is still missing.\r\n */\r\n private preprocessMarkdownTable(text: string): string {\r\n // ── Step 1: Break inline separator onto its own line ───────────\r\n // Pattern: the separator row consists only of |, -, :, and spaces.\r\n // We insert \\n before and after it.\r\n text = text.replace(\r\n /\\s*(\\|(?:\\s*:?-{2,}:?\\s*\\|){2,})\\s*/g,\r\n '\\n$1\\n'\r\n );\r\n // Clean up excess blank lines created by step 1\r\n text = text.replace(/\\n{3,}/g, '\\n\\n');\r\n\r\n // ── Step 2: Line-by-line processing ───────────────────────────\r\n const lines = text.split('\\n');\r\n const result: string[] = [];\r\n let inTable = false;\r\n\r\n const isPipeLine = (l: string) => {\r\n const t = l.trim();\r\n return t.startsWith('|') && t.split('|').length > 3;\r\n };\r\n const isSepLine = (l: string) =>\r\n /^\\|(?:\\s*:?-{2,}:?\\s*\\|){2,}\\s*$/.test(l.trim());\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const trimmed = line.trim();\r\n\r\n if (isPipeLine(trimmed) && !isSepLine(trimmed)) {\r\n if (!inTable) {\r\n inTable = true;\r\n // Insert blank line before table if preceded by non-empty text\r\n if (result.length > 0 && result[result.length - 1].trim() !== '') {\r\n result.push('');\r\n }\r\n result.push(line);\r\n // Inject separator if the next line isn't one\r\n const next = (i + 1 < lines.length) ? lines[i + 1] : '';\r\n if (!isSepLine(next)) {\r\n const cols = trimmed.split('|').filter(c => c.trim() !== '').length;\r\n result.push('| ' + Array(cols).fill('---').join(' | ') + ' |');\r\n }\r\n } else {\r\n result.push(line); // data row\r\n }\r\n } else if (isSepLine(trimmed)) {\r\n if (!inTable) inTable = true; // edge-case: separator before header\r\n result.push(line);\r\n } else {\r\n inTable = false;\r\n result.push(line);\r\n }\r\n }\r\n\r\n return result.join('\\n');\r\n }\r\n\r\n // ─── Private ───────────────────────────────────────────\r\n\r\n private handleError(error: any): void {\r\n const status = error?.status;\r\n if (status === 401 || status === 403) {\r\n const msg = status === 401 ? 'Token inválido o expirado' : 'Sin permisos para este sistema';\r\n this.authError.set(`🔒 ${msg}`);\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: `⚠️ ${msg}. Verifica el token y el systemId configurados.`,\r\n sender: 'bot',\r\n timestamp: new Date()\r\n }]);\r\n } else {\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: `Error: ${error.error?.message || error.error?.error || 'No se pudo procesar la consulta'}`,\r\n sender: 'bot',\r\n timestamp: new Date()\r\n }]);\r\n }\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n }\r\n\r\n private stopPipelineSteps(): void {\r\n this.pipelineStep = '';\r\n }\r\n\r\n private scrollToBottom(): void {\r\n if (this.chatContainer) {\r\n const el = this.chatContainer.nativeElement;\r\n el.scrollTop = el.scrollHeight;\r\n }\r\n }\r\n\r\n // ─── Session Persistence ──────────────────────────\r\n\r\n private buildSessionKey(): string {\r\n const cfg = this.resolvedConfig();\r\n if (!cfg.token || !cfg.systemId) return '';\r\n // Simple hash-like key from systemId + first 8 chars of token\r\n const tokenPrefix = cfg.token.substring(0, 8);\r\n return `${this.STORAGE_PREFIX}${cfg.systemId}_${tokenPrefix}`;\r\n }\r\n\r\n private saveSession(): void {\r\n if (!this.sessionKey) return;\r\n try {\r\n const data = this.messages().map(m => ({\r\n id: m.id,\r\n text: m.text,\r\n sender: m.sender,\r\n timestamp: m.timestamp,\r\n traceData: m.traceData\r\n }));\r\n localStorage.setItem(this.sessionKey, JSON.stringify(data));\r\n } catch { /* ignore quota errors */ }\r\n }\r\n\r\n private loadSession(): void {\r\n if (!this.sessionKey) return;\r\n try {\r\n const raw = localStorage.getItem(this.sessionKey);\r\n if (!raw) { this.messages.set([]); return; }\r\n const data: any[] = JSON.parse(raw);\r\n // Validate data is an array of valid message objects\r\n if (!Array.isArray(data) || data.length === 0) {\r\n this.messages.set([]);\r\n return;\r\n }\r\n const msgs: ChatMessage[] = data\r\n .filter(m => m && typeof m.text === 'string' && typeof m.sender === 'string')\r\n .map(m => ({\r\n ...m,\r\n timestamp: new Date(m.timestamp)\r\n }));\r\n this.messages.set(msgs);\r\n this.messageId = msgs.length > 0 ? Math.max(...msgs.map(m => m.id)) + 1 : 0;\r\n this.shouldScroll = true;\r\n } catch {\r\n // Corrupted session data — wipe it and start fresh\r\n try { localStorage.removeItem(this.sessionKey); } catch { /* ignore */ }\r\n this.messages.set([]);\r\n }\r\n }\r\n\r\n private clearSession(): void {\r\n if (this.sessionKey) {\r\n try { localStorage.removeItem(this.sessionKey); } catch {}\r\n }\r\n }\r\n\r\n /** Called when another tab modifies localStorage */\r\n private onStorageChange(e: StorageEvent): void {\r\n if (!this.sessionKey || e.key !== this.sessionKey) return;\r\n if (e.newValue === null) {\r\n // Session was cleared in another tab\r\n this.messages.set([]);\r\n } else {\r\n this.loadSession();\r\n }\r\n this.shouldScroll = true;\r\n }\r\n}\r\n","/*\r\n * Public API Surface of maquito-chat-plugin\r\n */\r\n\r\nexport type { IntelligentChatConfig, ChatMessage, PluginTheme } from './lib/intelligent-chat.models';\r\nexport { IntelligentChatService } from './lib/intelligent-chat.service';\r\nexport { IntelligentChatPluginComponent } from './lib/intelligent-chat-plugin.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"maquito-chat-plugin.mjs","sources":["../../../frontend/maquito-chat-plugin/src/lib/intelligent-chat.service.ts","../../../frontend/maquito-chat-plugin/src/lib/intelligent-chat-plugin.component.ts","../../../frontend/maquito-chat-plugin/src/public-api.ts","../../../frontend/maquito-chat-plugin/src/maquito-chat-plugin.ts"],"sourcesContent":["import { Injectable, inject, NgZone } from '@angular/core';\r\nimport { HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\n\r\n/**\r\n * Standalone HTTP service for the Maquito Chat Plugin.\r\n * Decoupled from any host app service — uses apiUrl + token from config.\r\n * Replicates exactly the same endpoints used by the Maquito Core API.\r\n *\r\n * IMPORTANT: The SSE streaming method runs OUTSIDE Angular Zone to prevent\r\n * change detection storms that freeze the host application's UI.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class IntelligentChatService {\r\n\r\n private http = inject(HttpClient);\r\n private ngZone = inject(NgZone);\r\n\r\n /**\r\n * Execute an intelligent query (POST /api/query).\r\n * Auth via X-Api-Key header.\r\n */\r\n executeIntelligentQuery(\r\n apiUrl: string,\r\n token: string,\r\n systemId: string,\r\n question: string,\r\n conversationHistory: { role: string; content: string }[] = [],\r\n baseContext?: string,\r\n skipPatternCache?: boolean,\r\n preferTableFormat?: boolean,\r\n userName?: string,\r\n personality?: string\r\n ): Observable<any> {\r\n const headers = this.buildHeaders(token);\r\n const body: any = { systemId, question, conversationHistory };\r\n if (baseContext) body.baseContext = baseContext;\r\n if (skipPatternCache) body.skipPatternCache = skipPatternCache;\r\n if (preferTableFormat !== undefined) body.preferTableFormat = preferTableFormat;\r\n if (userName) body.userName = userName;\r\n if (personality) body.personality = personality;\r\n return this.http.post<any>(`${apiUrl}/query`, body, { headers });\r\n }\r\n\r\n /**\r\n * Execute an intelligent query with SSE streaming progress.\r\n * Emits: { type: 'progress', step: string, message: string }\r\n * { type: 'result', data: any }\r\n *\r\n * The fetch + reader loop runs OUTSIDE Angular Zone to avoid\r\n * triggering change detection on every microtask (which would\r\n * freeze the host app). Emissions re-enter the zone via ngZone.run().\r\n */\r\n executeIntelligentQueryStream(\r\n apiUrl: string,\r\n token: string,\r\n systemId: string,\r\n question: string,\r\n conversationHistory: { role: string; content: string }[] = [],\r\n baseContext?: string,\r\n skipPatternCache?: boolean,\r\n preferTableFormat?: boolean,\r\n userName?: string,\r\n personality?: string\r\n ): Observable<{ type: 'progress' | 'result'; step?: string; message?: string; data?: any }> {\r\n const body: any = { systemId, question, conversationHistory };\r\n if (baseContext) body.baseContext = baseContext;\r\n if (skipPatternCache) body.skipPatternCache = skipPatternCache;\r\n if (preferTableFormat !== undefined) body.preferTableFormat = preferTableFormat;\r\n if (userName) body.userName = userName;\r\n if (personality) body.personality = personality;\r\n\r\n const FETCH_TIMEOUT_MS = 120_000; // 2 min max for the entire request\r\n const INACTIVITY_TIMEOUT_MS = 60_000; // 60s without data = abort\r\n const zone = this.ngZone;\r\n\r\n return new Observable(observer => {\r\n const abortController = new AbortController();\r\n\r\n // Run the entire fetch + SSE loop OUTSIDE Angular Zone\r\n // to prevent change detection storms that freeze the UI\r\n zone.runOutsideAngular(() => {\r\n // Combine user abort + global timeout\r\n let signal: AbortSignal;\r\n if (typeof AbortSignal.any === 'function') {\r\n signal = AbortSignal.any([abortController.signal, AbortSignal.timeout(FETCH_TIMEOUT_MS)]);\r\n } else {\r\n signal = abortController.signal;\r\n setTimeout(() => abortController.abort(), FETCH_TIMEOUT_MS);\r\n }\r\n\r\n fetch(`${apiUrl}/query/stream`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', 'X-Api-Key': token },\r\n body: JSON.stringify(body),\r\n signal\r\n }).then(async response => {\r\n if (!response.ok || !response.body) {\r\n zone.run(() => observer.error(new Error(`HTTP ${response.status}`)));\r\n return;\r\n }\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let lastDataTime = Date.now();\r\n\r\n while (true) {\r\n // Race reader vs inactivity timeout\r\n const readPromise = reader.read();\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n const elapsed = Date.now() - lastDataTime;\r\n const remaining = Math.max(INACTIVITY_TIMEOUT_MS - elapsed, 100);\r\n setTimeout(() => reject(new Error('SSE inactivity timeout: no data received for 60s')), remaining);\r\n });\r\n\r\n let result: ReadableStreamReadResult<Uint8Array>;\r\n try {\r\n result = await Promise.race([readPromise, timeoutPromise]);\r\n } catch (err) {\r\n reader.cancel();\r\n abortController.abort();\r\n zone.run(() => observer.error(err));\r\n return;\r\n }\r\n\r\n const { done, value } = result;\r\n if (done) break;\r\n lastDataTime = Date.now();\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n const parts = buffer.split('\\n\\n');\r\n buffer = parts.pop() || '';\r\n for (const part of parts) {\r\n const lines = part.split('\\n');\r\n let eventType = '';\r\n let eventData = '';\r\n for (const line of lines) {\r\n if (line.startsWith('event: ')) eventType = line.slice(7);\r\n else if (line.startsWith('data: ')) eventData = line.slice(6);\r\n }\r\n if (!eventType || !eventData) continue;\r\n try {\r\n const parsed = JSON.parse(eventData);\r\n if (eventType === 'progress') {\r\n // Emit progress WITHOUT re-entering Angular zone.\r\n // The component debounces these via requestAnimationFrame.\r\n observer.next({ type: 'progress', step: parsed.step, message: parsed.message });\r\n } else if (eventType === 'result') {\r\n zone.run(() => {\r\n observer.next({ type: 'result', data: parsed });\r\n observer.complete();\r\n });\r\n } else if (eventType === 'error') {\r\n zone.run(() => observer.error(parsed));\r\n }\r\n } catch { /* skip malformed JSON */ }\r\n }\r\n }\r\n if (!observer.closed) {\r\n zone.run(() => observer.complete());\r\n }\r\n }).catch(err => {\r\n if (err.name !== 'AbortError') {\r\n zone.run(() => observer.error(err));\r\n }\r\n });\r\n }); // end runOutsideAngular\r\n\r\n return () => abortController.abort();\r\n });\r\n }\r\n\r\n /**\r\n * Standard orchestration ask (POST /api/cortex/ask).\r\n * Used when intelligent query mode is disabled.\r\n */\r\n ask(apiUrl: string, token: string, text: string): Observable<any> {\r\n const headers = this.buildHeaders(token);\r\n return this.http.post<any>(`${apiUrl}/cortex/ask`, { text }, { headers });\r\n }\r\n\r\n private buildHeaders(token: string): HttpHeaders {\r\n return new HttpHeaders({ 'X-Api-Key': token });\r\n }\r\n}\r\n","import {\r\n Component, Input, inject, signal, computed, ViewChild, ElementRef,\r\n AfterViewChecked, OnChanges, OnInit, OnDestroy, SimpleChanges, HostListener\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';\r\nimport { marked } from 'marked';\r\nimport { Subscription } from 'rxjs';\r\nimport { IntelligentChatConfig, ChatMessage, PluginTheme } from './intelligent-chat.models';\r\nimport { IntelligentChatService } from './intelligent-chat.service';\r\n\r\n@Component({\r\n selector: 'intelligent-chat-plugin',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule],\r\n template: `\r\n <!-- Host theme overrides -->\r\n <div class=\"iq-theme-host\" [ngStyle]=\"themeStyles()\">\r\n\r\n <!-- Floating Bubble Button (hidden when expanded) -->\r\n @if (!isExpanded()) {\r\n <button\r\n class=\"iq-bubble\"\r\n [class.iq-bottom-left]=\"resolvedConfig().position === 'bottom-left'\"\r\n [class.iq-open]=\"isOpen()\"\r\n [style.position]=\"resolvedConfig().stickyBubble ? 'fixed' : 'absolute'\"\r\n (click)=\"toggleChat()\"\r\n [attr.aria-label]=\"isOpen() ? 'Cerrar chat' : 'Abrir chat'\"\r\n >\r\n @if (isOpen()) {\r\n <span class=\"iq-bubble-icon\">✕</span>\r\n } @else {\r\n @switch (resolvedConfig().bubbleIconType) {\r\n @case ('image') {\r\n <img [src]=\"resolvedConfig().bubbleImageUrl\" alt=\"Chat\" class=\"iq-bubble-img\" />\r\n }\r\n @case ('svg') {\r\n <span class=\"iq-bubble-svg\" [innerHTML]=\"sanitizedBubbleSvg()\"></span>\r\n }\r\n @default {\r\n <span class=\"iq-bubble-icon\">{{ resolvedConfig().bubbleIcon }}</span>\r\n }\r\n }\r\n }\r\n </button>\r\n }\r\n\r\n <!-- Chat Panel -->\r\n @if (isOpen()) {\r\n <div\r\n class=\"iq-panel\"\r\n [class.iq-bottom-left]=\"resolvedConfig().position === 'bottom-left'\"\r\n [class.iq-expanded]=\"isExpanded()\"\r\n [class]=\"resolvedConfig().themeClass || ''\"\r\n [style.position]=\"resolvedConfig().stickyBubble ? 'fixed' : 'absolute'\"\r\n >\r\n <!-- Header -->\r\n <div class=\"iq-header\">\r\n <span class=\"iq-header-title\">{{ resolvedConfig().title }}</span>\r\n <div class=\"iq-header-actions\">\r\n <button class=\"iq-header-btn\" (click)=\"clearChat()\" title=\"Limpiar chat\">🗑️</button>\r\n @if (resolvedConfig().allowExpand) {\r\n <button class=\"iq-header-btn iq-btn-expand\" (click)=\"toggleExpand()\" [title]=\"isExpanded() ? 'Contraer' : 'Expandir'\">\r\n {{ isExpanded() ? '⊡' : '⛶' }}\r\n </button>\r\n }\r\n <button class=\"iq-header-btn\" (click)=\"isExpanded() ? toggleExpand() : toggleChat()\">✕</button>\r\n </div>\r\n </div>\r\n\r\n <!-- Auth Error Banner -->\r\n @if (authError()) {\r\n <div class=\"iq-auth-error\">\r\n <span>🔒</span>\r\n <span>{{ authError() }}</span>\r\n </div>\r\n }\r\n\r\n <!-- Messages -->\r\n <div class=\"iq-messages\" #chatContainer>\r\n @if (messages().length === 0 && !authError()) {\r\n <div class=\"iq-empty\">\r\n <div class=\"iq-empty-icon\">\r\n @switch (resolvedConfig().bubbleIconType) {\r\n @case ('image') {\r\n <img [src]=\"resolvedConfig().bubbleImageUrl\" alt=\"\" class=\"iq-empty-img\" />\r\n }\r\n @case ('svg') {\r\n <span class=\"iq-empty-svg\" [innerHTML]=\"sanitizedBubbleSvg()\"></span>\r\n }\r\n @default {\r\n <span>{{ resolvedConfig().bubbleIcon }}</span>\r\n }\r\n }\r\n </div>\r\n <p>{{ resolvedConfig().welcomeTitle }}</p>\r\n <p class=\"iq-text-muted\">{{ resolvedConfig().welcomeSubtitle }}</p>\r\n </div>\r\n }\r\n\r\n @for (msg of messages(); track msg.id) {\r\n <div class=\"iq-msg\" [class.iq-msg-user]=\"msg.sender === 'user'\" [class.iq-msg-bot]=\"msg.sender === 'bot'\">\r\n <div class=\"iq-msg-content\">\r\n @if (msg.sender === 'bot') {\r\n <div class=\"iq-md\" [innerHTML]=\"renderMarkdown(msg.text)\" (click)=\"onMessageClick($event)\"></div>\r\n } @else {\r\n <p>{{ msg.text }}</p>\r\n }\r\n <span class=\"iq-msg-time\">{{ formatTime(msg.timestamp) }}</span>\r\n </div>\r\n @if (msg.sender === 'bot' && msg.traceData && resolvedConfig().showTrace) {\r\n <button class=\"iq-btn-trace\" (click)=\"showTrace(msg)\">🔍 Ver Traza</button>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Pipeline progress -->\r\n @if (isLoading()) {\r\n <div class=\"iq-msg iq-msg-bot\">\r\n <div class=\"iq-msg-content iq-pipeline\">\r\n <span class=\"iq-dot\"></span>\r\n <span class=\"iq-pipeline-text\">{{ pipelineStep }}</span>\r\n <button class=\"iq-cancel-btn\" (click)=\"cancelQuery()\" title=\"Cancelar consulta\">✕</button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Input -->\r\n <form class=\"iq-input-bar\" (ngSubmit)=\"sendMessage()\">\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"inputText\"\r\n name=\"message\"\r\n [placeholder]=\"resolvedConfig().placeholder!\"\r\n [disabled]=\"isLoading() || !!authError()\"\r\n autocomplete=\"off\"\r\n />\r\n <button type=\"submit\" class=\"iq-btn-send\" [disabled]=\"isLoading() || !inputText.trim() || !!authError()\">\r\n ➤\r\n </button>\r\n </form>\r\n </div>\r\n }\r\n\r\n <!-- Trace Modal Overlay -->\r\n @if (selectedTrace()) {\r\n <div class=\"iq-trace-overlay\" (click)=\"closeTrace()\">\r\n <div class=\"iq-trace-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"iq-trace-header\">\r\n <h3>🔍 Detalle de Traza</h3>\r\n <button class=\"iq-header-btn\" (click)=\"closeTrace()\">✕</button>\r\n </div>\r\n <div class=\"iq-trace-body\">\r\n @if (selectedTrace()?.fromCache !== undefined) {\r\n <div class=\"iq-trace-item\">\r\n <label>Origen</label>\r\n <code [class.iq-cache-hit]=\"selectedTrace()?.fromCache\">{{ selectedTrace()?.fromCache ? '📚 Desde Caché' : '🤖 Generado por GPT' }}</code>\r\n </div>\r\n }\r\n @if (selectedTrace()?.query) {\r\n <div class=\"iq-trace-item\">\r\n <label>Query Generada</label>\r\n <pre class=\"iq-query-code\">{{ selectedTrace()?.query }}</pre>\r\n </div>\r\n }\r\n @if (selectedTrace()?.explanation) {\r\n <div class=\"iq-trace-item\">\r\n <label>Explicación</label>\r\n <code>{{ selectedTrace()?.explanation }}</code>\r\n </div>\r\n }\r\n @if (selectedTrace()?.traceId) {\r\n <div class=\"iq-trace-item\">\r\n <label>Trace ID</label>\r\n <code>{{ selectedTrace()?.traceId }}</code>\r\n </div>\r\n }\r\n @if (selectedTrace()?.data) {\r\n <div class=\"iq-trace-item\">\r\n <label>Datos Retornados</label>\r\n <pre>{{ selectedTrace()?.data | json }}</pre>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Link Modal Overlay -->\r\n @if (modalUrl()) {\r\n <div class=\"iq-link-overlay\" (click)=\"closeLinkModal()\">\r\n <div class=\"iq-link-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"iq-link-header\">\r\n @if (showHomeBtn()) {\r\n <button class=\"iq-header-btn iq-back-btn\" (click)=\"iframeGoHome()\" title=\"Volver al inicio\">🏠</button>\r\n }\r\n <span class=\"iq-link-title\" [title]=\"modalUrl()!\">{{ modalUrl() }}</span>\r\n <div class=\"iq-link-actions\">\r\n <a [href]=\"modalUrl()!\" target=\"_blank\" rel=\"noopener\" class=\"iq-header-btn\" title=\"Abrir en nueva pestaña\">↗</a>\r\n <button class=\"iq-header-btn\" (click)=\"closeLinkModal()\">✕</button>\r\n </div>\r\n </div>\r\n <div class=\"iq-iframe-wrapper\">\r\n @if (isModalImage()) {\r\n <img [src]=\"modalUrl()!\" class=\"iq-modal-img\" alt=\"Imagen\" />\r\n } @else {\r\n @if (modalLoading()) {\r\n <div class=\"iq-iframe-loader\">\r\n <div class=\"iq-spinner\"></div>\r\n <span class=\"iq-loader-text\">Cargando...</span>\r\n </div>\r\n }\r\n <iframe #linkIframe [src]=\"sanitizedModalUrl()\" class=\"iq-link-iframe\"\r\n [class.iq-iframe-hidden]=\"modalLoading()\"\r\n (load)=\"onIframeLoaded()\"></iframe>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n </div><!-- /iq-theme-host -->\r\n `,\r\n styles: [`\r\n /* ========= CSS Custom Properties (overridable by host) ========= */\r\n :host {\r\n --iq-primary: #1a3a5c;\r\n --iq-primary-light: #2a5a8c;\r\n --iq-accent: #00d4aa;\r\n --iq-accent-light: #33e0be;\r\n --iq-bg: #1e1e2f;\r\n --iq-bg-card: #252538;\r\n --iq-bg-tertiary: #35354a;\r\n --iq-text: #ffffff;\r\n --iq-text-secondary: #a0a0b0;\r\n --iq-text-muted: #6c6c7c;\r\n --iq-border: #3a3a4d;\r\n --iq-radius: 12px;\r\n --iq-bubble-size: 56px;\r\n --iq-panel-width: 400px;\r\n --iq-panel-height: 520px;\r\n --iq-z: 10000;\r\n --iq-font: 'Inter', 'Roboto', -apple-system, BlinkMacSystemFont, sans-serif;\r\n font-family: var(--iq-font);\r\n }\r\n\r\n /* ========= Bubble ========= */\r\n .iq-bubble {\r\n position: fixed;\r\n bottom: 24px;\r\n right: 24px;\r\n z-index: var(--iq-z);\r\n width: var(--iq-bubble-size);\r\n height: var(--iq-bubble-size);\r\n border-radius: 50%;\r\n border: none;\r\n background: linear-gradient(135deg, var(--iq-accent), var(--iq-accent-light));\r\n color: var(--iq-bg);\r\n font-size: 1.6rem;\r\n cursor: pointer;\r\n box-shadow: 0 4px 16px rgba(0, 212, 170, 0.4);\r\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n .iq-bubble:hover {\r\n transform: scale(1.1);\r\n box-shadow: 0 6px 24px rgba(0, 212, 170, 0.5);\r\n }\r\n .iq-bubble .iq-bubble-icon {\r\n font-size: 1.5rem;\r\n pointer-events: none;\r\n }\r\n\r\n .iq-bubble-img {\r\n width: 60%; height: 60%;\r\n object-fit: contain; border-radius: 50%;\r\n pointer-events: none;\r\n }\r\n\r\n .iq-bubble-svg {\r\n width: 60%; height: 60%;\r\n display: flex; align-items: center; justify-content: center;\r\n pointer-events: none;\r\n }\r\n .iq-bubble-svg :deep(svg) { width: 100%; height: 100%; }\r\n\r\n .iq-bubble.iq-open {\r\n background: var(--iq-bg-tertiary);\r\n color: var(--iq-text);\r\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\r\n font-size: 1.2rem;\r\n }\r\n .iq-bubble.iq-bottom-left {\r\n right: auto;\r\n left: 24px;\r\n }\r\n .iq-bubble-icon { line-height: 1; }\r\n\r\n /* ========= Panel ========= */\r\n .iq-panel {\r\n position: fixed;\r\n bottom: 92px;\r\n right: 24px;\r\n z-index: var(--iq-z);\r\n width: var(--iq-panel-width);\r\n height: var(--iq-panel-height);\r\n background: var(--iq-bg);\r\n border: 1px solid var(--iq-border);\r\n border-radius: var(--iq-radius);\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n box-shadow: 0 12px 40px rgba(0,0,0,0.5);\r\n animation: iq-slide-up 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n .iq-panel.iq-bottom-left {\r\n right: auto;\r\n left: 24px;\r\n }\r\n /* ========= Expanded / Fullscreen ========= */\r\n .iq-panel.iq-expanded {\r\n width: 100vw !important;\r\n height: 100vh !important;\r\n top: 0 !important;\r\n left: 0 !important;\r\n right: 0 !important;\r\n bottom: 0 !important;\r\n border: none;\r\n border-radius: 0;\r\n overflow: clip;\r\n z-index: calc(var(--iq-z) + 5);\r\n animation: iq-expand 0.3s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n .iq-btn-expand {\r\n font-size: 1.1rem !important;\r\n }\r\n @keyframes iq-expand {\r\n from { opacity: 0.8; transform: scale(0.95); }\r\n to { opacity: 1; transform: scale(1); }\r\n }\r\n @keyframes iq-slide-up {\r\n from { opacity: 0; transform: translateY(16px) scale(0.96); }\r\n to { opacity: 1; transform: translateY(0) scale(1); }\r\n }\r\n\r\n /* ========= Header ========= */\r\n .iq-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 12px 16px;\r\n border-bottom: 1px solid var(--iq-border);\r\n background: var(--iq-bg-card);\r\n }\r\n .iq-header-title {\r\n font-weight: 600;\r\n font-size: 0.95rem;\r\n color: var(--iq-text);\r\n }\r\n .iq-header-actions {\r\n display: flex;\r\n gap: 4px;\r\n }\r\n .iq-header-btn {\r\n background: none;\r\n border: none;\r\n color: var(--iq-text-muted);\r\n cursor: pointer;\r\n font-size: 1rem;\r\n padding: 4px 6px;\r\n border-radius: 4px;\r\n transition: all 0.15s;\r\n }\r\n .iq-header-btn:hover {\r\n color: var(--iq-text);\r\n background: rgba(255,255,255,0.08);\r\n }\r\n\r\n /* ========= Auth Error ========= */\r\n .iq-auth-error {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 10px 16px;\r\n background: rgba(220, 53, 69, 0.15);\r\n color: #ff6b7a;\r\n font-size: 0.8rem;\r\n border-bottom: 1px solid rgba(220, 53, 69, 0.25);\r\n }\r\n\r\n /* ========= Messages ========= */\r\n .iq-messages {\r\n flex: 1;\r\n min-height: 0;\r\n overflow-y: auto;\r\n padding: 12px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 10px;\r\n }\r\n\r\n .iq-empty {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n text-align: center;\r\n color: var(--iq-text-secondary);\r\n }\r\n .iq-empty-icon { font-size: 3rem; margin-bottom: 8px; display: flex; align-items: center; justify-content: center; }\r\n .iq-empty-img { width: 48px; height: 48px; object-fit: contain; border-radius: 8px; }\r\n .iq-empty-svg { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; }\r\n .iq-empty-svg :deep(svg) { width: 100%; height: 100%; }\r\n .iq-empty p { font-size: 0.95rem; margin: 2px 0; }\r\n .iq-text-muted { color: var(--iq-text-muted) !important; font-size: 0.8rem !important; }\r\n\r\n .iq-msg { display: flex; flex-direction: column; max-width: 85%; }\r\n .iq-msg-user { align-self: flex-end; }\r\n .iq-msg-bot { align-self: flex-start; max-width: 100%; }\r\n\r\n .iq-msg-user .iq-msg-content {\r\n background: linear-gradient(135deg, var(--iq-primary), var(--iq-primary-light));\r\n border-radius: 12px 12px 0 12px;\r\n }\r\n .iq-msg-bot .iq-msg-content {\r\n background: var(--iq-bg-tertiary);\r\n border-radius: 12px 12px 12px 0;\r\n }\r\n .iq-msg-content {\r\n padding: 10px 14px;\r\n color: var(--iq-text);\r\n font-size: 0.85rem;\r\n line-height: 1.45;\r\n }\r\n .iq-msg-content p { margin: 0; white-space: pre-wrap; }\r\n .iq-msg-time {\r\n display: block;\r\n margin-top: 4px;\r\n font-size: 0.65rem;\r\n color: rgba(255,255,255,0.5);\r\n }\r\n\r\n /* Markdown rendered content */\r\n .iq-md { line-height: 1.5; overflow-x: auto; max-width: 100%; }\r\n .iq-md :first-child { margin-top: 0; }\r\n .iq-md :last-child { margin-bottom: 0; }\r\n .iq-md p { margin: 0 0 0.4em 0; }\r\n .iq-md p:last-child { margin-bottom: 0; }\r\n .iq-md strong { color: var(--iq-accent); }\r\n .iq-md ul, .iq-md ol { margin: 0.3em 0; padding-left: 1.2em; }\r\n .iq-md li { margin: 0.15em 0; }\r\n .iq-md code {\r\n background: rgba(0,0,0,0.3);\r\n padding: 0.15em 0.4em;\r\n border-radius: 3px;\r\n font-size: 0.82em;\r\n }\r\n .iq-md pre {\r\n background: rgba(0,0,0,0.3);\r\n padding: 0.8em;\r\n border-radius: 6px;\r\n overflow-x: auto;\r\n font-size: 0.78em;\r\n margin: 0.4em 0;\r\n }\r\n .iq-md pre code { background: none; padding: 0; }\r\n .iq-md table {\r\n width: max-content; min-width: 100%;\r\n border-collapse: separate; border-spacing: 0;\r\n margin: 0.5em 0; font-size: 0.75rem;\r\n border-radius: 6px; overflow: hidden;\r\n }\r\n .iq-md thead th {\r\n background: rgba(99,102,241,0.18); color: #a5b4fc;\r\n font-weight: 600; text-align: left;\r\n padding: 0.5em 0.8em; border-bottom: 2px solid rgba(99,102,241,0.3);\r\n white-space: nowrap; font-size: 0.7rem;\r\n text-transform: uppercase; letter-spacing: 0.05em;\r\n }\r\n .iq-md tbody td {\r\n padding: 0.4em 0.8em; border-bottom: 1px solid rgba(255,255,255,0.06);\r\n white-space: nowrap; color: var(--iq-text-secondary);\r\n }\r\n .iq-md tbody tr:hover { background: rgba(99,102,241,0.08); }\r\n\r\n /* Inline images in bot messages – small thumbnails, click to enlarge */\r\n .iq-md img {\r\n max-height: 80px; max-width: 120px; object-fit: cover;\r\n border-radius: 8px; margin: 6px 4px 6px 0;\r\n display: inline-block; vertical-align: middle;\r\n border: 1px solid rgba(255,255,255,0.15);\r\n box-shadow: 0 1px 4px rgba(0,0,0,0.25);\r\n cursor: pointer; transition: transform 0.15s, box-shadow 0.15s;\r\n }\r\n .iq-md img:hover {\r\n transform: scale(1.05);\r\n box-shadow: 0 3px 12px rgba(99,102,241,0.35);\r\n border-color: var(--iq-accent);\r\n }\r\n .iq-md img[alt*=\"logo\"], .iq-md img[alt*=\"marca\"] {\r\n max-height: 28px; max-width: 90px; object-fit: contain;\r\n border: none; box-shadow: none; border-radius: 4px;\r\n background: rgba(255,255,255,0.9); padding: 2px 6px;\r\n }\r\n /* Trace button */\r\n .iq-btn-trace {\r\n align-self: flex-start; margin-top: 4px;\r\n background: transparent; border: 1px solid var(--iq-border);\r\n color: var(--iq-text-secondary); font-size: 0.7rem;\r\n padding: 3px 8px; border-radius: 4px; cursor: pointer;\r\n transition: all 0.15s;\r\n }\r\n .iq-btn-trace:hover { border-color: var(--iq-accent); color: var(--iq-accent); }\r\n\r\n /* Pipeline loading indicator */\r\n .iq-pipeline {\r\n display: flex; align-items: center; gap: 8px;\r\n animation: iq-fade-in 0.3s ease-out;\r\n }\r\n .iq-dot {\r\n width: 8px; height: 8px; border-radius: 50%;\r\n background: var(--iq-accent);\r\n animation: iq-pulse 1s ease-in-out infinite;\r\n }\r\n .iq-pipeline-text {\r\n font-size: 0.8rem; color: var(--iq-text-muted); font-style: italic;\r\n flex: 1;\r\n }\r\n .iq-cancel-btn {\r\n background: transparent; border: 1px solid var(--iq-border);\r\n color: var(--iq-text-muted); font-size: 0.7rem;\r\n padding: 2px 8px; border-radius: 4px; cursor: pointer;\r\n transition: all 0.15s; flex-shrink: 0;\r\n }\r\n .iq-cancel-btn:hover {\r\n border-color: #ff6b6b; color: #ff6b6b; background: rgba(255, 107, 107, 0.1);\r\n }\r\n @keyframes iq-pulse {\r\n 0%, 100% { opacity: 1; transform: scale(1); }\r\n 50% { opacity: 0.4; transform: scale(0.7); }\r\n }\r\n @keyframes iq-fade-in {\r\n from { opacity: 0; transform: translateX(-6px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n }\r\n\r\n /* ========= Input Bar ========= */\r\n .iq-input-bar {\r\n display: flex; gap: 8px;\r\n padding: 10px 12px;\r\n border-top: 1px solid var(--iq-border);\r\n background: var(--iq-bg-card);\r\n }\r\n .iq-input-bar input {\r\n flex: 1; padding: 8px 12px;\r\n background: var(--iq-bg-tertiary);\r\n border: 1px solid var(--iq-border);\r\n border-radius: 8px;\r\n color: var(--iq-text);\r\n font-size: 0.85rem;\r\n font-family: var(--iq-font);\r\n outline: none;\r\n transition: border-color 0.15s;\r\n }\r\n .iq-input-bar input:focus { border-color: var(--iq-accent); }\r\n .iq-input-bar input::placeholder { color: var(--iq-text-muted); }\r\n .iq-input-bar input:disabled { opacity: 0.5; }\r\n .iq-btn-send {\r\n width: 36px; height: 36px;\r\n border-radius: 8px; border: none;\r\n background: linear-gradient(135deg, var(--iq-accent), var(--iq-accent-light));\r\n color: var(--iq-bg); font-size: 1rem;\r\n cursor: pointer; transition: all 0.2s;\r\n display: flex; align-items: center; justify-content: center;\r\n }\r\n .iq-btn-send:hover:not(:disabled) { box-shadow: 0 0 12px rgba(0,212,170,0.4); transform: translateY(-1px); }\r\n .iq-btn-send:disabled { opacity: 0.4; cursor: not-allowed; }\r\n\r\n /* ========= Trace Modal ========= */\r\n .iq-trace-overlay {\r\n position: fixed; inset: 0;\r\n z-index: calc(var(--iq-z) + 10);\r\n background: rgba(0,0,0,0.6);\r\n display: flex; align-items: center; justify-content: center;\r\n animation: iq-fade-in 0.2s ease-out;\r\n }\r\n .iq-trace-modal {\r\n width: 90%; max-width: 520px; max-height: 80vh;\r\n background: var(--iq-bg); border: 1px solid var(--iq-border);\r\n border-radius: var(--iq-radius);\r\n display: flex; flex-direction: column; overflow: hidden;\r\n box-shadow: 0 20px 50px rgba(0,0,0,0.6);\r\n }\r\n .iq-trace-header {\r\n display: flex; align-items: center; justify-content: space-between;\r\n padding: 14px 16px; border-bottom: 1px solid var(--iq-border);\r\n }\r\n .iq-trace-header h3 { margin: 0; font-size: 0.95rem; color: var(--iq-text); }\r\n .iq-trace-body {\r\n flex: 1; overflow-y: auto; padding: 16px;\r\n display: flex; flex-direction: column; gap: 12px;\r\n }\r\n .iq-trace-item label {\r\n display: block; font-size: 0.7rem; color: var(--iq-text-muted);\r\n margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.05em;\r\n }\r\n .iq-trace-item code {\r\n display: block; padding: 8px;\r\n background: var(--iq-bg-tertiary); border-radius: 4px;\r\n font-family: monospace; font-size: 0.8rem; color: var(--iq-accent);\r\n word-break: break-all;\r\n }\r\n .iq-trace-item pre {\r\n margin: 0; padding: 8px;\r\n background: var(--iq-bg-tertiary); border-radius: 4px;\r\n font-family: monospace; font-size: 0.7rem;\r\n overflow-x: auto; max-height: 180px; color: var(--iq-text-secondary);\r\n }\r\n .iq-cache-hit { background: rgba(16,185,129,0.15) !important; color: #10b981 !important; }\r\n .iq-query-code { color: var(--iq-accent) !important; }\r\n\r\n /* ========= Link Modal ========= */\r\n .iq-link-overlay {\r\n position: fixed; inset: 0;\r\n z-index: calc(var(--iq-z) + 20);\r\n background: rgba(0,0,0,0.7);\r\n display: flex; align-items: center; justify-content: center;\r\n animation: iq-fade-in 0.2s ease-out;\r\n backdrop-filter: blur(4px);\r\n }\r\n .iq-link-modal {\r\n width: 94vw; height: 92vh;\r\n background: var(--iq-bg); border: 1px solid var(--iq-border);\r\n border-radius: var(--iq-radius);\r\n display: flex; flex-direction: column; overflow: hidden;\r\n box-shadow: 0 24px 60px rgba(0,0,0,0.7);\r\n animation: iq-expand 0.25s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n .iq-link-header {\r\n display: flex; align-items: center; justify-content: space-between;\r\n padding: 10px 16px; border-bottom: 1px solid var(--iq-border);\r\n background: var(--iq-bg-card); gap: 12px; min-height: 44px;\r\n }\r\n .iq-link-title {\r\n flex: 1; font-size: 0.78rem; color: var(--iq-text-secondary);\r\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\r\n font-family: monospace;\r\n }\r\n .iq-link-actions {\r\n display: flex; gap: 4px; flex-shrink: 0;\r\n }\r\n .iq-link-actions a {\r\n text-decoration: none;\r\n }\r\n .iq-back-btn {\r\n flex-shrink: 0; font-size: 1.1rem;\r\n transition: transform 0.15s ease;\r\n }\r\n .iq-back-btn:hover {\r\n transform: translateX(-2px);\r\n }\r\n .iq-iframe-wrapper {\r\n flex: 1; position: relative; overflow: hidden;\r\n }\r\n .iq-link-iframe {\r\n width: 100%; height: 100%; border: none;\r\n background: #fff;\r\n transition: opacity 0.3s ease;\r\n }\r\n .iq-iframe-hidden {\r\n opacity: 0;\r\n }\r\n .iq-modal-img {\r\n width: 100%; height: 100%;\r\n object-fit: contain;\r\n background: #1a1a2e;\r\n }\r\n .iq-iframe-loader {\r\n position: absolute; inset: 0;\r\n display: flex; flex-direction: column;\r\n align-items: center; justify-content: center;\r\n background: var(--iq-bg);\r\n gap: 16px; z-index: 2;\r\n }\r\n .iq-spinner {\r\n width: 40px; height: 40px;\r\n border: 3px solid var(--iq-border);\r\n border-top-color: var(--iq-accent);\r\n border-radius: 50%;\r\n animation: iq-spin 0.8s linear infinite;\r\n }\r\n .iq-loader-text {\r\n font-size: 0.85rem; color: var(--iq-text-secondary);\r\n font-weight: 500;\r\n }\r\n @keyframes iq-spin {\r\n to { transform: rotate(360deg); }\r\n }\r\n\r\n /* ========= Link Modal — markdown link styling ========= */\r\n .iq-md a {\r\n color: var(--iq-accent); text-decoration: underline;\r\n cursor: pointer; transition: color 0.15s;\r\n }\r\n .iq-md a:hover {\r\n color: var(--iq-accent-light);\r\n }\r\n\r\n @media (max-width: 480px) {\r\n .iq-link-modal {\r\n width: 100vw; height: 100dvh;\r\n border-radius: 0;\r\n }\r\n .iq-link-header { padding: 8px 12px; }\r\n .iq-link-title { font-size: 0.7rem; }\r\n }\r\n\r\n /* ========= Scrollbar ========= */\r\n .iq-messages::-webkit-scrollbar { width: 5px; }\r\n .iq-messages::-webkit-scrollbar-track { background: transparent; }\r\n .iq-messages::-webkit-scrollbar-thumb { background: var(--iq-border); border-radius: 4px; }\r\n .iq-trace-body::-webkit-scrollbar { width: 5px; }\r\n .iq-trace-body::-webkit-scrollbar-track { background: transparent; }\r\n .iq-trace-body::-webkit-scrollbar-thumb { background: var(--iq-border); border-radius: 4px; }\r\n /* Wider scrollbar in fullscreen for easier grabbing */\r\n .iq-expanded .iq-messages::-webkit-scrollbar { width: 8px; }\r\n .iq-expanded .iq-messages { scrollbar-gutter: stable; }\r\n\r\n /* ========= Mobile Small Screens ========= */\r\n @media (max-width: 480px) {\r\n .iq-bubble {\r\n bottom: 16px;\r\n right: 16px;\r\n width: 48px;\r\n height: 48px;\r\n font-size: 1.3rem;\r\n }\r\n .iq-bubble.iq-bottom-left {\r\n left: 16px;\r\n }\r\n .iq-bubble .iq-bubble-icon { font-size: 1.2rem; }\r\n\r\n .iq-panel {\r\n right: 8px;\r\n left: 8px;\r\n bottom: 72px;\r\n width: auto !important;\r\n max-width: calc(100vw - 16px);\r\n height: calc(100dvh - 90px);\r\n max-height: calc(100dvh - 90px);\r\n }\r\n .iq-panel.iq-bottom-left {\r\n left: 8px;\r\n right: 8px;\r\n }\r\n .iq-panel.iq-expanded {\r\n top: 0 !important;\r\n left: 0 !important;\r\n right: 0 !important;\r\n bottom: 0 !important;\r\n width: 100vw !important;\r\n height: 100dvh !important;\r\n max-height: 100dvh !important;\r\n max-width: 100vw !important;\r\n border-radius: 0;\r\n }\r\n\r\n .iq-header {\r\n padding: 10px 12px;\r\n }\r\n .iq-header-title { font-size: 0.85rem; }\r\n .iq-header-btn { padding: 6px 8px; min-width: 32px; min-height: 32px; }\r\n\r\n .iq-messages { padding: 8px; gap: 8px; }\r\n\r\n .iq-msg { max-width: 92%; }\r\n .iq-msg-bot { max-width: 100%; }\r\n .iq-msg-content { padding: 8px 10px; font-size: 0.8rem; }\r\n\r\n .iq-md { overflow-x: auto; -webkit-overflow-scrolling: touch; }\r\n .iq-md table { font-size: 0.65rem; min-width: unset; }\r\n .iq-md thead th { padding: 0.35em 0.5em; font-size: 0.6rem; }\r\n .iq-md tbody td { padding: 0.3em 0.5em; font-size: 0.65rem; }\r\n\r\n .iq-empty-icon { font-size: 2.5rem; }\r\n .iq-empty p { font-size: 0.85rem; }\r\n\r\n .iq-input-bar { padding: 8px 10px; gap: 6px; }\r\n .iq-input-bar input { font-size: 16px; padding: 8px 10px; }\r\n .iq-btn-send { width: 38px; height: 38px; flex-shrink: 0; }\r\n\r\n .iq-trace-modal {\r\n width: calc(100vw - 24px);\r\n max-height: 90dvh;\r\n }\r\n .iq-trace-header { padding: 12px; }\r\n .iq-trace-header h3 { font-size: 0.85rem; }\r\n .iq-trace-body { padding: 12px; }\r\n .iq-trace-item pre { font-size: 0.65rem; max-height: 140px; }\r\n }\r\n\r\n /* ========= Landscape Mobile — fit floating panel ========= */\r\n @media (max-height: 500px) and (orientation: landscape) {\r\n .iq-bubble {\r\n bottom: 8px;\r\n right: 8px;\r\n width: 44px;\r\n height: 44px;\r\n font-size: 1.1rem;\r\n }\r\n .iq-bubble.iq-bottom-left { left: 8px; }\r\n\r\n .iq-panel {\r\n right: 60px;\r\n left: 8px;\r\n bottom: 8px;\r\n top: 8px;\r\n width: auto !important;\r\n max-width: calc(100vw - 76px);\r\n height: auto !important;\r\n max-height: calc(100dvh - 16px);\r\n border-radius: var(--iq-radius);\r\n }\r\n .iq-panel.iq-bottom-left {\r\n left: 60px;\r\n right: 8px;\r\n }\r\n .iq-panel.iq-expanded {\r\n top: 0 !important;\r\n left: 0 !important;\r\n right: 0 !important;\r\n bottom: 0 !important;\r\n width: 100vw !important;\r\n height: 100dvh !important;\r\n max-height: 100dvh !important;\r\n max-width: 100vw !important;\r\n border-radius: 0;\r\n }\r\n\r\n .iq-header { padding: 6px 12px; }\r\n .iq-header-title { font-size: 0.8rem; }\r\n .iq-messages { padding: 6px 10px; gap: 6px; }\r\n .iq-empty-icon { font-size: 1.8rem; margin-bottom: 4px; }\r\n .iq-empty p { font-size: 0.78rem; margin: 1px 0; }\r\n .iq-input-bar { padding: 6px 10px; }\r\n .iq-input-bar input { font-size: 16px; padding: 6px 10px; }\r\n .iq-btn-send { width: 32px; height: 32px; }\r\n }\r\n `]\r\n})\r\nexport class IntelligentChatPluginComponent implements AfterViewChecked, OnChanges, OnInit, OnDestroy {\r\n @ViewChild('chatContainer') private chatContainer!: ElementRef;\r\n\r\n @Input() config!: IntelligentChatConfig;\r\n\r\n private chatService = inject(IntelligentChatService);\r\n private hostEl = inject(ElementRef);\r\n\r\n // State\r\n isOpen = signal(false);\r\n isExpanded = signal(false);\r\n messages = signal<ChatMessage[]>([]);\r\n isLoading = signal(false);\r\n selectedTrace = signal<any>(null);\r\n authError = signal<string | null>(null);\r\n modalUrl = signal<string | null>(null);\r\n isModalImage = computed(() => {\r\n const url = this.modalUrl();\r\n if (!url) return false;\r\n return /\\.(jpg|jpeg|png|gif|webp|svg|bmp)(\\?.*)?$/i.test(url);\r\n });\r\n modalLoading = signal(false);\r\n showHomeBtn = signal(false);\r\n private originalModalUrl = '';\r\n private modalReadyForNav = false;\r\n private navReadyTimer: any = null;\r\n inputText = '';\r\n private currentSubscription?: Subscription;\r\n\r\n // Pipeline step (driven by real SSE events from backend)\r\n pipelineStep = '';\r\n\r\n private messageId = 0;\r\n private shouldScroll = false;\r\n\r\n // ─── Markdown Cache (avoids re-parsing on every CD cycle) ────\r\n private mdCache = new Map<string, SafeHtml>();\r\n // ─── Debounce progress updates to avoid CD storms ────\r\n private pendingPipelineStep: string | null = null;\r\n private rafId: number | null = null;\r\n\r\n // ─── Session Persistence ──────────────────────────\r\n private readonly STORAGE_PREFIX = 'iq_chat_session_';\r\n private sessionKey = '';\r\n private storageListener = (e: StorageEvent) => this.onStorageChange(e);\r\n\r\n /** Resolved config with defaults applied */\r\n private sanitizer = inject(DomSanitizer);\r\n\r\n resolvedConfig = signal<Required<IntelligentChatConfig>>({\r\n apiUrl: '',\r\n systemId: '',\r\n token: '',\r\n useIntelligentQuery: true,\r\n skipPatterns: true,\r\n baseContext: '',\r\n showTrace: false,\r\n showPipelineSteps: true,\r\n preferTableFormat: true,\r\n title: 'Maquito Chat',\r\n placeholder: 'Escribe tu consulta aquí...',\r\n welcomeTitle: '¡Hola! Soy Maquito.',\r\n welcomeSubtitle: 'Escribe tu consulta para comenzar.',\r\n position: 'bottom-right',\r\n bubbleIcon: '🤖',\r\n bubbleIconType: 'emoji',\r\n bubbleImageUrl: '',\r\n bubbleSvg: '',\r\n themeClass: '',\r\n stickyBubble: true,\r\n allowExpand: false,\r\n theme: {},\r\n userName: '',\r\n personality: ''\r\n });\r\n\r\n /** Map theme object → CSS variable overrides */\r\n themeStyles = computed(() => {\r\n const t = this.resolvedConfig().theme || {};\r\n const map: Record<string, string> = {};\r\n const pairs: [keyof PluginTheme, string][] = [\r\n ['primary', '--iq-primary'], ['primaryLight', '--iq-primary-light'],\r\n ['accent', '--iq-accent'], ['accentLight', '--iq-accent-light'],\r\n ['bg', '--iq-bg'], ['bgCard', '--iq-bg-card'], ['bgTertiary', '--iq-bg-tertiary'],\r\n ['text', '--iq-text'], ['textSecondary', '--iq-text-secondary'],\r\n ['textMuted', '--iq-text-muted'], ['border', '--iq-border']\r\n ];\r\n for (const [key, cssVar] of pairs) {\r\n if (t[key]) map[cssVar] = t[key]!;\r\n }\r\n return map;\r\n });\r\n\r\n /** Sanitised SVG HTML for bubble */\r\n sanitizedBubbleSvg = computed<SafeHtml>(() => {\r\n const raw = this.resolvedConfig().bubbleSvg || '';\r\n return this.sanitizer.bypassSecurityTrustHtml(raw);\r\n });\r\n\r\n /** Sanitised URL for the link modal iframe */\r\n sanitizedModalUrl = computed<SafeResourceUrl>(() => {\r\n const url = this.modalUrl() || '';\r\n return this.sanitizer.bypassSecurityTrustResourceUrl(url);\r\n });\r\n\r\n ngOnInit(): void {\r\n window.addEventListener('storage', this.storageListener);\r\n // Self-heal: always reset transient state on init to prevent\r\n // corrupted sessions from freezing the page\r\n this.isLoading.set(false);\r\n this.pipelineStep = '';\r\n this.isExpanded.set(false);\r\n this.setHostScrollLock(false);\r\n this.currentSubscription?.unsubscribe();\r\n this.currentSubscription = undefined;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n window.removeEventListener('storage', this.storageListener);\r\n this.cancelQuery();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['config'] && this.config) {\r\n this.resolvedConfig.set({\r\n apiUrl: this.config.apiUrl || '',\r\n systemId: this.config.systemId || '',\r\n token: this.config.token || '',\r\n useIntelligentQuery: this.config.useIntelligentQuery ?? true,\r\n skipPatterns: this.config.skipPatterns ?? true,\r\n baseContext: this.config.baseContext || '',\r\n showTrace: this.config.showTrace ?? false,\r\n showPipelineSteps: this.config.showPipelineSteps ?? true,\r\n preferTableFormat: this.config.preferTableFormat ?? true,\r\n title: this.config.title || 'Maquito Chat',\r\n placeholder: this.config.placeholder || 'Escribe tu consulta aquí...',\r\n welcomeTitle: this.config.welcomeTitle || '¡Hola! Soy Maquito.',\r\n welcomeSubtitle: this.config.welcomeSubtitle || 'Escribe tu consulta para comenzar.',\r\n position: this.config.position || 'bottom-right',\r\n bubbleIcon: this.config.bubbleIcon || '🤖',\r\n bubbleIconType: this.config.bubbleIconType || 'emoji',\r\n bubbleImageUrl: this.config.bubbleImageUrl || '',\r\n bubbleSvg: this.config.bubbleSvg || '',\r\n themeClass: this.config.themeClass || '',\r\n stickyBubble: this.config.stickyBubble ?? true,\r\n allowExpand: this.config.allowExpand ?? false,\r\n theme: this.config.theme || {},\r\n userName: this.config.userName || '',\r\n personality: this.config.personality || ''\r\n });\r\n // Cancel any in-flight query when config changes\r\n this.cancelQuery();\r\n // Rebuild session key when config changes\r\n const newKey = this.buildSessionKey();\r\n if (newKey !== this.sessionKey) {\r\n this.sessionKey = newKey;\r\n this.loadSession();\r\n }\r\n // Clear auth error when config changes (user may be testing a new token)\r\n this.authError.set(null);\r\n }\r\n }\r\n\r\n ngAfterViewChecked(): void {\r\n if (this.shouldScroll) {\r\n this.scrollToBottom();\r\n this.shouldScroll = false;\r\n }\r\n }\r\n\r\n toggleChat(): void {\r\n this.isOpen.update(v => !v);\r\n if (!this.isOpen()) {\r\n this.isExpanded.set(false);\r\n this.setHostScrollLock(false);\r\n this.cancelQuery();\r\n }\r\n if (this.isOpen()) this.shouldScroll = true;\r\n }\r\n\r\n toggleExpand(): void {\r\n this.isExpanded.update(v => !v);\r\n this.setHostScrollLock(this.isExpanded());\r\n }\r\n\r\n /** Lock/unlock the host page scroll to prevent its scrollbar from overlapping ours */\r\n private setHostScrollLock(lock: boolean): void {\r\n document.body.style.overflow = lock ? 'hidden' : '';\r\n // Also target common host containers\r\n const mc = document.querySelector('.main-container') as HTMLElement;\r\n if (mc) mc.style.overflow = lock ? 'hidden' : '';\r\n }\r\n\r\n sendMessage(): void {\r\n const text = this.inputText.trim();\r\n if (!text) return;\r\n\r\n const cfg = this.resolvedConfig();\r\n\r\n // Validate required config\r\n if (!cfg.token) {\r\n this.authError.set('Token no configurado. El plugin requiere un token técnico válido.');\r\n return;\r\n }\r\n if (!cfg.apiUrl) {\r\n this.authError.set('API URL no configurada.');\r\n return;\r\n }\r\n\r\n this.authError.set(null);\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text,\r\n sender: 'user',\r\n timestamp: new Date()\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n this.inputText = '';\r\n this.isLoading.set(true);\r\n\r\n if (cfg.showPipelineSteps) {\r\n this.pipelineStep = '⏳ Procesando...';\r\n } else {\r\n this.pipelineStep = '⏳ Procesando...';\r\n }\r\n\r\n if (cfg.useIntelligentQuery && cfg.systemId) {\r\n // Build conversation history from previous messages (last 6 pairs)\r\n const history = this.messages()\r\n .filter(m => m.sender === 'user' || m.sender === 'bot')\r\n .slice(-12)\r\n .map(msg => ({\r\n role: msg.sender === 'user' ? 'user' : 'assistant',\r\n content: msg.text\r\n }));\r\n\r\n const ctx = cfg.baseContext?.trim() || undefined;\r\n\r\n if (cfg.showPipelineSteps) {\r\n // Use SSE streaming for real-time pipeline progress\r\n this.currentSubscription = this.chatService.executeIntelligentQueryStream(\r\n cfg.apiUrl, cfg.token, cfg.systemId, text, history, ctx, cfg.skipPatterns, cfg.preferTableFormat,\r\n cfg.userName || undefined, cfg.personality || undefined\r\n ).subscribe({\r\n next: (event) => {\r\n if (event.type === 'progress') {\r\n // Debounce progress updates — queue for next animation frame\r\n // to avoid triggering Angular CD on every SSE chunk\r\n this.pendingPipelineStep = event.message || '';\r\n if (this.rafId === null) {\r\n this.rafId = requestAnimationFrame(() => {\r\n this.rafId = null;\r\n if (this.pendingPipelineStep !== null) {\r\n this.pipelineStep = this.pendingPipelineStep;\r\n this.pendingPipelineStep = null;\r\n }\r\n });\r\n }\r\n return;\r\n } else if (event.type === 'result') {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n const response = event.data;\r\n const responseText = response.success\r\n ? (response.response || 'Consulta ejecutada correctamente')\r\n : (response.error || 'Error en la consulta');\r\n\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: responseText,\r\n sender: 'bot',\r\n timestamp: new Date(),\r\n traceData: {\r\n traceId: response.traceId,\r\n fromCache: response.fromCache,\r\n fromContext: response.fromContext,\r\n query: response.query,\r\n explanation: response.explanation,\r\n patternId: response.patternId,\r\n data: response.data\r\n }\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n }\r\n },\r\n error: (error) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.setHostScrollLock(false);\r\n this.handleError(error);\r\n }\r\n });\r\n } else {\r\n // Fallback: use standard non-streaming endpoint\r\n this.currentSubscription = this.chatService.executeIntelligentQuery(\r\n cfg.apiUrl, cfg.token, cfg.systemId, text, history, ctx, cfg.skipPatterns, cfg.preferTableFormat,\r\n cfg.userName || undefined, cfg.personality || undefined\r\n ).subscribe({\r\n next: (response: any) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n const responseText = response.success\r\n ? (response.response || 'Consulta ejecutada correctamente')\r\n : (response.error || 'Error en la consulta');\r\n\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: responseText,\r\n sender: 'bot',\r\n timestamp: new Date(),\r\n traceData: {\r\n traceId: response.traceId,\r\n fromCache: response.fromCache,\r\n fromContext: response.fromContext,\r\n query: response.query,\r\n explanation: response.explanation,\r\n patternId: response.patternId,\r\n data: response.data\r\n }\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n },\r\n error: (error) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.setHostScrollLock(false);\r\n this.handleError(error);\r\n }\r\n });\r\n }\r\n } else {\r\n // Standard orchestration (non-intelligent)\r\n this.currentSubscription = this.chatService.ask(cfg.apiUrl, cfg.token, text).subscribe({\r\n next: (response) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: response.data?.response || 'Sin respuesta',\r\n sender: 'bot',\r\n timestamp: new Date(),\r\n traceData: {\r\n traceId: response.traceId,\r\n responseTime: response.data?.processingTime,\r\n appliedRules: response.data?.appliedRules,\r\n decisions: response.data?.decisions\r\n }\r\n }]);\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n },\r\n error: (error) => {\r\n this.pipelineStep = '';\r\n this.isLoading.set(false);\r\n this.setHostScrollLock(false);\r\n this.handleError(error);\r\n }\r\n });\r\n }\r\n }\r\n\r\n cancelQuery(): void {\r\n this.currentSubscription?.unsubscribe();\r\n this.currentSubscription = undefined;\r\n this.isLoading.set(false);\r\n this.pipelineStep = '';\r\n this.setHostScrollLock(false);\r\n }\r\n\r\n clearChat(): void {\r\n this.messages.set([]);\r\n this.selectedTrace.set(null);\r\n this.authError.set(null);\r\n this.clearSession();\r\n }\r\n\r\n showTrace(msg: ChatMessage): void {\r\n this.selectedTrace.set(msg.traceData);\r\n }\r\n\r\n closeTrace(): void {\r\n this.selectedTrace.set(null);\r\n }\r\n\r\n // ─── Link Modal ────────────────────────────────\r\n openLinkModal(url: string): void {\r\n this.modalLoading.set(true);\r\n this.showHomeBtn.set(false);\r\n this.modalReadyForNav = false;\r\n clearTimeout(this.navReadyTimer);\r\n this.originalModalUrl = url;\r\n this.modalUrl.set(url);\r\n }\r\n\r\n closeLinkModal(): void {\r\n this.modalUrl.set(null);\r\n this.modalLoading.set(false);\r\n this.showHomeBtn.set(false);\r\n this.modalReadyForNav = false;\r\n clearTimeout(this.navReadyTimer);\r\n this.originalModalUrl = '';\r\n }\r\n\r\n onIframeLoaded(): void {\r\n this.modalLoading.set(false);\r\n if (this.modalReadyForNav) {\r\n // A load AFTER the initial page settled = real navigation\r\n this.showHomeBtn.set(true);\r\n } else {\r\n // Initial page load (may fire multiple times for SPAs/redirects)\r\n // Wait 1s of stability before treating next loads as navigation\r\n clearTimeout(this.navReadyTimer);\r\n this.navReadyTimer = setTimeout(() => { this.modalReadyForNav = true; }, 1000);\r\n }\r\n }\r\n\r\n iframeGoHome(): void {\r\n const iframe = this.hostEl.nativeElement.querySelector('.iq-link-iframe') as HTMLIFrameElement;\r\n if (iframe && this.originalModalUrl) {\r\n this.modalLoading.set(true);\r\n this.showHomeBtn.set(false);\r\n this.modalReadyForNav = false;\r\n clearTimeout(this.navReadyTimer);\r\n iframe.src = this.originalModalUrl;\r\n }\r\n }\r\n\r\n /** Intercept clicks on <a> and <img> tags inside rendered markdown */\r\n onMessageClick(event: MouseEvent): void {\r\n const target = event.target as HTMLElement;\r\n\r\n // Clicking an image opens it full-size in the modal\r\n if (target.tagName === 'IMG') {\r\n const src = (target as HTMLImageElement).src;\r\n if (src) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.openLinkModal(src);\r\n return;\r\n }\r\n }\r\n\r\n const anchor = target.closest('a') as HTMLAnchorElement | null;\r\n if (anchor && anchor.href) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.openLinkModal(anchor.href);\r\n }\r\n }\r\n\r\n formatTime(date: Date): string {\r\n return date.toLocaleTimeString('es-CL', { hour: '2-digit', minute: '2-digit' });\r\n }\r\n\r\n renderMarkdown(text: string): SafeHtml {\r\n if (!text) return '';\r\n\r\n // Return cached result if available (avoids re-parsing on every CD cycle)\r\n const cached = this.mdCache.get(text);\r\n if (cached) return cached;\r\n\r\n try {\r\n // Safety valve: if text is extremely long, skip regex-heavy preprocessing\r\n // to avoid catastrophic backtracking that freezes the browser\r\n let preprocessed = text.length < 100_000 ? this.preprocessMarkdownTable(text) : text;\r\n\r\n // Encode spaces in markdown image & link URLs:  and [text](url)\r\n if (preprocessed.length < 100_000) {\r\n preprocessed = preprocessed.replace(/(!?\\[[^\\]]*\\])\\(([^)]+)\\)/g,\r\n (_match, bracket, url) => `${bracket}(${url.replace(/ /g, '%20')})`);\r\n }\r\n\r\n let html = marked.parse(preprocessed, { breaks: true }) as string;\r\n // Inject inline styles + onerror on <img> to force small thumbnails & hide broken ones\r\n const imgStyle = `style=\"max-height:48px;max-width:100px;object-fit:contain;border-radius:6px;cursor:pointer;display:inline-block;vertical-align:middle;margin:2px 4px;border:1px solid rgba(255,255,255,0.15);box-shadow:0 1px 3px rgba(0,0,0,0.2);\"`;\r\n html = html.replace(/<img /g, `<img ${imgStyle} onerror=\"this.style.display='none'\" `);\r\n const result = this.sanitizer.bypassSecurityTrustHtml(html);\r\n this.mdCache.set(text, result);\r\n return result;\r\n } catch {\r\n return text;\r\n }\r\n }\r\n\r\n /**\r\n * Pre-process text to ensure pipe-delimited tables render as HTML tables.\r\n *\r\n * The API often returns header + separator + data on ONE line, e.g.:\r\n * \"| Col1 | Col2 | |---|---| | Val1 | Val2 |\"\r\n *\r\n * Step 1: Find the dash-separator pattern (|---|---|) and break the line\r\n * around it so each part (header / separator / data rows) is its\r\n * own line.\r\n * Step 2: Line-by-line cleanup — ensure a blank line exists before the\r\n * first pipe-row and inject a separator if one is still missing.\r\n */\r\n private preprocessMarkdownTable(text: string): string {\r\n // ── Step 1: Break inline separator onto its own line ───────────\r\n // Pattern: the separator row consists only of |, -, :, and spaces.\r\n // We insert \\n before and after it.\r\n text = text.replace(\r\n /\\s*(\\|(?:\\s*:?-{2,}:?\\s*\\|){2,})\\s*/g,\r\n '\\n$1\\n'\r\n );\r\n // Clean up excess blank lines created by step 1\r\n text = text.replace(/\\n{3,}/g, '\\n\\n');\r\n\r\n // ── Step 2: Line-by-line processing ───────────────────────────\r\n const lines = text.split('\\n');\r\n const result: string[] = [];\r\n let inTable = false;\r\n\r\n const isPipeLine = (l: string) => {\r\n const t = l.trim();\r\n return t.startsWith('|') && t.split('|').length > 3;\r\n };\r\n const isSepLine = (l: string) =>\r\n /^\\|(?:\\s*:?-{2,}:?\\s*\\|){2,}\\s*$/.test(l.trim());\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n const trimmed = line.trim();\r\n\r\n if (isPipeLine(trimmed) && !isSepLine(trimmed)) {\r\n if (!inTable) {\r\n inTable = true;\r\n // Insert blank line before table if preceded by non-empty text\r\n if (result.length > 0 && result[result.length - 1].trim() !== '') {\r\n result.push('');\r\n }\r\n result.push(line);\r\n // Inject separator if the next line isn't one\r\n const next = (i + 1 < lines.length) ? lines[i + 1] : '';\r\n if (!isSepLine(next)) {\r\n const cols = trimmed.split('|').filter(c => c.trim() !== '').length;\r\n result.push('| ' + Array(cols).fill('---').join(' | ') + ' |');\r\n }\r\n } else {\r\n result.push(line); // data row\r\n }\r\n } else if (isSepLine(trimmed)) {\r\n if (!inTable) inTable = true; // edge-case: separator before header\r\n result.push(line);\r\n } else {\r\n inTable = false;\r\n result.push(line);\r\n }\r\n }\r\n\r\n return result.join('\\n');\r\n }\r\n\r\n // ─── Private ───────────────────────────────────────────\r\n\r\n private handleError(error: any): void {\r\n const status = error?.status;\r\n if (status === 401 || status === 403) {\r\n const msg = status === 401 ? 'Token inválido o expirado' : 'Sin permisos para este sistema';\r\n this.authError.set(`🔒 ${msg}`);\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: `⚠️ ${msg}. Verifica el token y el systemId configurados.`,\r\n sender: 'bot',\r\n timestamp: new Date()\r\n }]);\r\n } else {\r\n this.messages.update(msgs => [...msgs, {\r\n id: this.messageId++,\r\n text: `Error: ${error.error?.message || error.error?.error || 'No se pudo procesar la consulta'}`,\r\n sender: 'bot',\r\n timestamp: new Date()\r\n }]);\r\n }\r\n this.saveSession();\r\n this.shouldScroll = true;\r\n }\r\n\r\n private stopPipelineSteps(): void {\r\n this.pipelineStep = '';\r\n }\r\n\r\n private scrollToBottom(): void {\r\n if (this.chatContainer) {\r\n const el = this.chatContainer.nativeElement;\r\n el.scrollTop = el.scrollHeight;\r\n }\r\n }\r\n\r\n // ─── Session Persistence ──────────────────────────\r\n\r\n private buildSessionKey(): string {\r\n const cfg = this.resolvedConfig();\r\n if (!cfg.token || !cfg.systemId) return '';\r\n // Simple hash-like key from systemId + first 8 chars of token\r\n const tokenPrefix = cfg.token.substring(0, 8);\r\n return `${this.STORAGE_PREFIX}${cfg.systemId}_${tokenPrefix}`;\r\n }\r\n\r\n private saveSession(): void {\r\n if (!this.sessionKey) return;\r\n try {\r\n const data = this.messages().map(m => ({\r\n id: m.id,\r\n text: m.text,\r\n sender: m.sender,\r\n timestamp: m.timestamp,\r\n traceData: m.traceData\r\n }));\r\n localStorage.setItem(this.sessionKey, JSON.stringify(data));\r\n } catch { /* ignore quota errors */ }\r\n }\r\n\r\n private loadSession(): void {\r\n if (!this.sessionKey) return;\r\n try {\r\n const raw = localStorage.getItem(this.sessionKey);\r\n if (!raw) { this.messages.set([]); return; }\r\n const data: any[] = JSON.parse(raw);\r\n // Validate data is an array of valid message objects\r\n if (!Array.isArray(data) || data.length === 0) {\r\n this.messages.set([]);\r\n return;\r\n }\r\n const msgs: ChatMessage[] = data\r\n .filter(m => m && typeof m.text === 'string' && typeof m.sender === 'string')\r\n .map(m => ({\r\n ...m,\r\n timestamp: new Date(m.timestamp)\r\n }));\r\n this.messages.set(msgs);\r\n this.messageId = msgs.length > 0 ? Math.max(...msgs.map(m => m.id)) + 1 : 0;\r\n this.shouldScroll = true;\r\n } catch {\r\n // Corrupted session data — wipe it and start fresh\r\n try { localStorage.removeItem(this.sessionKey); } catch { /* ignore */ }\r\n this.messages.set([]);\r\n }\r\n }\r\n\r\n private clearSession(): void {\r\n if (this.sessionKey) {\r\n try { localStorage.removeItem(this.sessionKey); } catch {}\r\n }\r\n }\r\n\r\n /** Called when another tab modifies localStorage */\r\n private onStorageChange(e: StorageEvent): void {\r\n if (!this.sessionKey || e.key !== this.sessionKey) return;\r\n if (e.newValue === null) {\r\n // Session was cleared in another tab\r\n this.messages.set([]);\r\n } else {\r\n this.loadSession();\r\n }\r\n this.shouldScroll = true;\r\n }\r\n}\r\n","/*\r\n * Public API Surface of maquito-chat-plugin\r\n */\r\n\r\nexport type { IntelligentChatConfig, ChatMessage, PluginTheme } from './lib/intelligent-chat.models';\r\nexport { IntelligentChatService } from './lib/intelligent-chat.service';\r\nexport { IntelligentChatPluginComponent } from './lib/intelligent-chat-plugin.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -152,6 +152,9 @@ declare class IntelligentChatPluginComponent implements AfterViewChecked, OnChan
|
|
|
152
152
|
pipelineStep: string;
|
|
153
153
|
private messageId;
|
|
154
154
|
private shouldScroll;
|
|
155
|
+
private mdCache;
|
|
156
|
+
private pendingPipelineStep;
|
|
157
|
+
private rafId;
|
|
155
158
|
private readonly STORAGE_PREFIX;
|
|
156
159
|
private sessionKey;
|
|
157
160
|
private storageListener;
|