@m6d/cortex-client 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"m6d-cortex-client.mjs","sources":["../../../projects/cortex-client/src/lib/config.ts","../../../projects/cortex-client/src/lib/services/cortex-websocket.service.ts","../../../projects/cortex-client/src/lib/services/cortex-chat.service.ts","../../../projects/cortex-client/src/lib/pipes/marked.pipe.ts","../../../projects/cortex-client/src/lib/components/message-text-part/message-text-part.component.ts","../../../projects/cortex-client/src/lib/components/message-text-part/message-text-part.component.html","../../../projects/cortex-client/src/lib/components/message-reasoning-part/message-reasoning-part.component.ts","../../../projects/cortex-client/src/lib/components/message-reasoning-part/message-reasoning-part.component.html","../../../projects/cortex-client/src/lib/pipes/highlight.pipe.ts","../../../projects/cortex-client/src/lib/components/json-tree/json-tree.component.ts","../../../projects/cortex-client/src/lib/components/json-tree/json-tree.component.html","../../../projects/cortex-client/src/lib/components/message-tool-call-part/message-tool-call-part.component.ts","../../../projects/cortex-client/src/lib/components/message-tool-call-part/message-tool-call-part.component.html","../../../projects/cortex-client/src/lib/components/message-capture-file-part/message-capture-files-part.component.ts","../../../projects/cortex-client/src/lib/components/message-capture-file-part/message-capture-files-part.component.html","../../../projects/cortex-client/src/lib/components/message-tool-call-animated/message-tool-call-animated.component.ts","../../../projects/cortex-client/src/lib/components/message-tool-call-animated/message-tool-call-animated.component.html","../../../projects/cortex-client/src/lib/components/message-reasoning-animated/message-reasoning-animated.component.ts","../../../projects/cortex-client/src/lib/components/message-reasoning-animated/message-reasoning-animated.component.html","../../../projects/cortex-client/src/lib/components/message-part/message-part.component.ts","../../../projects/cortex-client/src/lib/components/message-part/message-part.component.html","../../../projects/cortex-client/src/lib/components/message/message.component.ts","../../../projects/cortex-client/src/lib/components/message/message.component.html","../../../projects/cortex-client/src/lib/components/message-list/message-list.component.ts","../../../projects/cortex-client/src/lib/components/message-list/message-list.component.html","../../../projects/cortex-client/src/lib/i18n/translate-loader.ts","../../../projects/cortex-client/src/lib/components/chat-widget/chat-widget.component.ts","../../../projects/cortex-client/src/lib/components/chat-widget/chat-widget.component.html","../../../projects/cortex-client/src/lib/pipes/pretty-json.pipe.ts","../../../projects/cortex-client/src/public-api.ts","../../../projects/cortex-client/src/m6d-cortex-client.ts"],"sourcesContent":["import { Signal, Type, InjectionToken } from '@angular/core';\n\nexport type CortexClientTransport = {\n baseUrl: string | Signal<string>;\n getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;\n};\n\nexport type CortexClientConfig = {\n locale: Signal<string>;\n theme?: CortexClientTheme;\n transport: CortexClientTransport;\n wsUrl?: string;\n toolComponents?: Record<string, Type<unknown>>;\n onToolCall?: (toolCall: {\n toolName: string;\n toolCallId: string;\n args: Record<string, unknown>;\n dynamic: boolean;\n }) => Promise<unknown> | unknown;\n};\n\nexport type CortexClientTheme = {\n primaryColor?: string;\n backgroundColor?: string;\n surfaceColor?: string;\n textColor?: string;\n borderRadius?: string;\n customProperties?: Record<string, string>;\n};\n\nexport const CORTEX_CLIENT_CONFIG = new InjectionToken<CortexClientConfig>('CORTEX_CLIENT_CONFIG');\n","import { inject, Injectable, NgZone, Signal } from '@angular/core';\nimport { Observable, retry, share, timer } from 'rxjs';\nimport { CORTEX_CLIENT_CONFIG } from '../config';\nimport { WsEvent } from '../ws-events';\n\n@Injectable()\nexport class CortexClientWebSocketService {\n private readonly events$: Observable<WsEvent>;\n\n constructor() {\n const config = inject(CORTEX_CLIENT_CONFIG);\n const ngZone = inject(NgZone);\n\n this.events$ = new Observable<WsEvent>((subscriber) => {\n const wsUrl = config.wsUrl ?? deriveWsUrl(config.transport.baseUrl);\n let ws: WebSocket | undefined;\n\n Promise.resolve(config.transport.getAuthHeaders()).then((headers) => {\n if (subscriber.closed) return;\n\n const fullWsUrl = appendTokenToUrl(wsUrl, headers);\n ws = new WebSocket(fullWsUrl);\n\n ws.addEventListener('message', (event) => {\n let parsed: WsEvent;\n try {\n parsed = JSON.parse(event.data);\n } catch {\n return;\n }\n ngZone.run(() => subscriber.next(parsed));\n });\n\n ws.addEventListener('error', (e) => subscriber.error(e));\n ws.addEventListener('close', () => subscriber.error(new Error('WebSocket closed')));\n });\n\n return () => ws?.close();\n }).pipe(\n retry({\n delay: (_: unknown, retryCount: number) =>\n timer(Math.min(1000 * 2 ** (retryCount - 1), 30_000)),\n }),\n share(),\n );\n }\n\n get events() {\n return this.events$;\n }\n}\n\nfunction deriveWsUrl(baseUrl: string | Signal<string>) {\n const url = typeof baseUrl === 'string' ? baseUrl : baseUrl();\n const parsed = new URL(url, window.location.origin);\n parsed.protocol = parsed.protocol === 'https:' ? 'wss:' : 'ws:';\n parsed.pathname = parsed.pathname.replace(/\\/$/, '') + '/ws';\n return parsed.toString();\n}\n\nfunction appendTokenToUrl(wsUrl: string, headers: Record<string, string>) {\n const authHeader = headers['Authorization'] ?? headers['authorization'];\n if (!authHeader?.startsWith('Bearer ')) return wsUrl;\n\n const token = authHeader.slice(7);\n const separator = wsUrl.includes('?') ? '&' : '?';\n return `${wsUrl}${separator}token=${encodeURIComponent(token)}`;\n}\n","import { DestroyRef, inject, Injectable, Signal, signal } from '@angular/core';\nimport { Chat } from '@ai-sdk/angular';\nimport { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls, UIMessage } from 'ai';\nimport { concatMap, defer, finalize, map, of, pipe, Subject, switchMap, tap } from 'rxjs';\nimport { fromPromise } from 'rxjs/internal/observable/innerFrom';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CORTEX_CLIENT_CONFIG, CortexClientConfig } from '../config';\nimport { CortexClientWebSocketService } from './cortex-websocket.service';\n\nexport type Thread = {\n id: string;\n title?: string;\n createdAt?: string;\n updatedAt?: string;\n};\n\n@Injectable()\nexport class CortexChatService {\n readonly threads = signal<Thread[] | undefined>(undefined);\n readonly selectedThread = signal<Thread | undefined>(undefined);\n readonly chat = signal<Chat | undefined>(undefined);\n readonly isLoadingMessages = signal(false);\n readonly isAgentWorking = signal(false);\n readonly hasPendingToolCalls = signal(false);\n\n private events = new Subject<'onThreadSelected' | 'onSend' | 'onData' | 'onError' | 'onFinish'>();\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n private readonly wsService = inject(CortexClientWebSocketService);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n this.reloadThreads().subscribe();\n this.subscribeToWsEvents();\n }\n\n get events$() {\n return this.events.asObservable();\n }\n\n selectThread(thread: Thread, options?: { skipLoadingMessages?: boolean }) {\n if (this.isLoadingMessages()) return of();\n if (this.selectedThread()?.id === thread.id) return of();\n\n return (\n options?.skipLoadingMessages\n ? of([])\n : defer(() => {\n this.isLoadingMessages.set(true);\n return fromPromise(this.fetchJson<UIMessage[]>(`/threads/${thread.id}/messages`)).pipe(\n finalize(() => this.isLoadingMessages.set(false)),\n );\n })\n ).pipe(\n tap((messages) => {\n const chat = new Chat({\n id: thread.id,\n sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,\n\n onData: () => {\n this.events.next('onData');\n },\n\n onToolCall: async ({ toolCall }) => {\n if (!this.config.onToolCall) return;\n\n const tc = toolCall as unknown as {\n toolName: string;\n toolCallId: string;\n args: Record<string, unknown>;\n dynamic: boolean;\n };\n const result = this.config.onToolCall(tc);\n if (result == null) return;\n\n const output = result instanceof Promise ? await result : result;\n chat.addToolOutput({\n tool: tc.toolName,\n toolCallId: tc.toolCallId,\n output,\n });\n },\n\n onError: () => {\n this.isAgentWorking.set(false);\n this.hasPendingToolCalls.set(false);\n this.events.next('onError');\n },\n\n onFinish: () => {\n const lastAssistantMsg = [...chat.messages]\n .reverse()\n .find((m) => m.role === 'assistant');\n const pending = lastAssistantMsg?.parts?.some(\n (p) =>\n p.type.startsWith('tool-') &&\n (p as { state?: string }).state !== 'output-available' &&\n (p as { state?: string }).state !== 'output-error' &&\n (p as { state?: string }).state !== 'output-denied',\n );\n\n if (pending) {\n this.hasPendingToolCalls.set(true);\n } else {\n this.isAgentWorking.set(false);\n this.hasPendingToolCalls.set(false);\n }\n this.events.next('onFinish');\n },\n\n messages: messages as UIMessage[],\n transport: new DefaultChatTransport({\n api: this.resolveUrl('/chat'),\n headers: async () => await this.resolveHeaders(),\n prepareSendMessagesRequest: ({ messages, id, body, ...rest }) => {\n this.isAgentWorking.set(true);\n this.hasPendingToolCalls.set(false);\n return {\n ...rest,\n body: {\n ...body,\n id,\n messages: [messages.at(-1)],\n },\n };\n },\n }),\n });\n\n fixChat(chat);\n this.chat.set(chat);\n this.selectedThread.set(thread);\n\n // Check if loaded messages have pending tool calls\n const lastAssistantMsg = [...messages].reverse().find((m) => m.role === 'assistant');\n const pending = lastAssistantMsg?.parts?.some(\n (p) =>\n p.type.startsWith('tool-') &&\n (p as { state?: string }).state !== 'output-available' &&\n (p as { state?: string }).state !== 'output-error' &&\n (p as { state?: string }).state !== 'output-denied',\n );\n if (pending) {\n this.hasPendingToolCalls.set(true);\n }\n\n this.events.next('onThreadSelected');\n }),\n );\n }\n\n deselectThread() {\n if (!this.selectedThread()) return;\n\n this.abort();\n this.selectedThread.set(undefined);\n this.chat.set(undefined);\n }\n\n send(prompt: string) {\n if (this.isAgentWorking()) return of();\n\n const ensureThread = this.selectedThread()\n ? of(undefined)\n : fromPromise(\n this.fetchJson<Thread>('/threads', {\n method: 'POST',\n body: JSON.stringify({ prompt }),\n }),\n ).pipe(\n switchMap((thread) =>\n this.selectThread(thread, { skipLoadingMessages: true }).pipe(map(() => undefined)),\n ),\n tap(() => this.reloadThreads().subscribe()),\n );\n\n return ensureThread.pipe(\n switchMap(() => fromPromise(this.chat()!.sendMessage({ text: prompt }))),\n tap(() => this.events.next('onSend')),\n );\n }\n\n abort() {\n const chat = this.chat();\n if (!chat || !this.isAgentWorking()) return;\n\n chat.stop();\n this.isAgentWorking.set(false);\n this.hasPendingToolCalls.set(false);\n\n const threadId = this.selectedThread()?.id;\n if (!threadId) return;\n this.reloadMessages(threadId).subscribe((messages) => {\n if (!this.chat()) return;\n this.chat()!.messages = messages;\n });\n }\n\n deleteThread(threadId: string) {\n if (this.selectedThread()?.id === threadId) this.deselectThread();\n\n return fromPromise(this.fetchJson(`/threads/${threadId}`, { method: 'DELETE' })).pipe(\n concatMap(() => this.reloadThreads()),\n );\n }\n\n private subscribeToWsEvents() {\n this.wsService.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {\n switch (event.type) {\n case 'thread:title-updated':\n this.onThreadTitleUpdated(event.payload);\n break;\n }\n });\n }\n\n private onThreadTitleUpdated(payload: { threadId: string; title: string }) {\n const current = this.threads();\n if (current) {\n this.threads.set(\n current.map((t) => (t.id === payload.threadId ? { ...t, title: payload.title } : t)),\n );\n }\n\n const selected = this.selectedThread();\n if (selected?.id === payload.threadId) {\n this.selectedThread.set({ ...selected, title: payload.title });\n }\n }\n\n private reloadThreads() {\n return fromPromise(this.fetchJson<Thread[]>('/threads')).pipe(\n tap((threads) => this.threads.set(threads)),\n );\n }\n\n private reloadMessages(threadId: string) {\n return fromPromise(this.fetchJson<UIMessage[]>(`/threads/${threadId}/messages`));\n }\n\n private resolveUrl(path: string) {\n const baseUrl = this.config.transport.baseUrl;\n const base = typeof baseUrl === 'string' ? baseUrl : (baseUrl as Signal<string>)();\n return base.replace(/\\/$/, '') + path;\n }\n\n private async resolveHeaders() {\n return await Promise.resolve(this.config.transport.getAuthHeaders());\n }\n\n private async fetchJson<T>(path: string, init?: RequestInit) {\n const url = this.resolveUrl(path);\n const headers = await this.resolveHeaders();\n const res = await fetch(url, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n ...init?.headers,\n },\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n const text = await res.text();\n return text ? (JSON.parse(text) as T) : (undefined as T);\n }\n}\n\n/**\n * Override snapshot to avoid structuredClone failing on\n * Object.defineProperty getter/setter parts.\n */\nfunction fixChat(chat: Chat) {\n function deepClone<T>(value: T): T {\n if (value === null || value === undefined) return value;\n if (typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(deepClone) as unknown as T;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>)) {\n result[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n return result as T;\n }\n\n (chat as unknown as { state: { snapshot: unknown } }).state.snapshot = deepClone;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { marked } from 'marked';\nimport DOMPurify from 'dompurify';\n\n@Pipe({\n name: 'marked',\n standalone: true,\n})\nexport class MarkedPipe implements PipeTransform {\n constructor(private readonly sanitizer: DomSanitizer) {}\n\n transform(value: string | undefined | null): SafeHtml {\n if (!value) {\n return '';\n }\n\n let html = marked.parse(value, { async: false }) as string;\n\n html = html\n .replace(/<table>/g, '<div style=\"overflow-x:auto\"><table style=\"width:auto\">')\n .replace(/<\\/table>/g, '</table></div>')\n .replace(/<(t[hd])([\\s>])/g, '<$1 style=\"padding:0.5rem 1rem\"$2');\n\n return this.sanitizer.bypassSecurityTrustHtml(DOMPurify.sanitize(html));\n }\n}\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { TextUIPart, UIMessage } from 'ai';\nimport { MarkedPipe } from '../../pipes/marked.pipe';\n\n@Component({\n selector: 'cortex-message-text-part',\n templateUrl: './message-text-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgClass, MarkedPipe],\n})\nexport class MessageTextPartComponent {\n public readonly role = input.required<UIMessage['role']>();\n public readonly textPart = input.required<TextUIPart>();\n}\n","<div\n class=\"w-full flex flex-col\"\n [ngClass]=\"{\n 'items-end': role() === 'assistant',\n 'items-start': role() === 'user',\n }\"\n>\n <div\n class=\"max-w-4/5 text-[13px] leading-relaxed p-4 rounded-2xl border border-slate-200 prose\"\n [ngClass]=\"{\n 'bg-slate-100 text-slate-700 ltr:rounded-br-none rtl:rounded-bl-none': role() === 'assistant',\n 'bg-slate-50 text-slate-700 ltr:rounded-bl-none rtl:rounded-br-none': role() === 'user',\n }\"\n [innerHTML]=\"textPart().text | marked\"\n ></div>\n</div>\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { ReasoningUIPart } from 'ai';\n\n@Component({\n selector: 'cortex-message-reasoning-part',\n templateUrl: './message-reasoning-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MessageReasoningPartComponent {\n public readonly reasoningPart = input.required<ReasoningUIPart>();\n}\n","@let p = reasoningPart();\n<details class=\"group w-full rounded-lg border border-slate-200 bg-slate-50 overflow-hidden\">\n <summary\n class=\"list-none [&::-webkit-details-marker]:hidden cursor-pointer select-none px-4 py-3 flex items-center gap-3\"\n >\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\n <span\n class=\"inline-flex h-6 w-6 items-center justify-center rounded bg-indigo-100 text-indigo-600\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M10 2C6.686 2 4 4.686 4 8c0 1.655.672 3.154 1.757 4.243.362.363.576.858.576 1.371V14.5a1 1 0 0 0 1 1h5.334a1 1 0 0 0 1-1v-.886c0-.513.214-1.008.576-1.371A5.978 5.978 0 0 0 16 8c0-3.314-2.686-6-6-6Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M7.5 17.5h5M8.5 8a2 2 0 0 1 2-2\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <div class=\"font-medium text-slate-700 text-sm\">Reasoning</div>\n @if (p.state) {\n <span\n class=\"inline-flex items-center rounded px-1.5 py-0.5 text-[11px] font-medium\"\n [class.bg-amber-100.text-amber-700]=\"p.state === 'streaming'\"\n [class.bg-emerald-100.text-emerald-700]=\"p.state === 'done'\"\n >\n {{ p.state === 'streaming' ? 'Streaming' : 'Done' }}\n </span>\n }\n </div>\n </div>\n </div>\n\n <span\n class=\"ml-auto inline-flex h-6 w-6 items-center justify-center rounded text-slate-400 transition group-open:rotate-180\"\n aria-hidden=\"true\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"m5.75 8.25 4.25 4.25 4.25-4.25\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </summary>\n\n <div class=\"px-4 pb-4\">\n <div class=\"mt-1 rounded bg-white border border-slate-200 p-3\">\n <pre\n class=\"m-0 whitespace-pre-wrap wrap-break-word font-mono text-xs leading-relaxed text-slate-700\"\n >{{ p.text.trim() ? p.text : 'No reasoning provided.' }}</pre\n >\n </div>\n </div>\n</details>\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport hljs from 'highlight.js/lib/core';\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport json from 'highlight.js/lib/languages/json';\nimport sql from 'highlight.js/lib/languages/sql';\n\nhljs.registerLanguage('javascript', javascript);\nhljs.registerLanguage('json', json);\nhljs.registerLanguage('cypher', sql);\n\n@Pipe({ name: 'highlight', standalone: true })\nexport class HighlightPipe implements PipeTransform {\n constructor(private readonly sanitizer: DomSanitizer) {}\n\n transform(code: string, lang: string): SafeHtml {\n if (!code) return '';\n\n const highlighted = hljs.getLanguage(lang)\n ? hljs.highlight(code, { language: lang }).value\n : this.escapeHtml(code);\n\n return this.sanitizer.bypassSecurityTrustHtml(highlighted);\n }\n\n private escapeHtml(str: string) {\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n@Component({\n selector: 'cortex-json-tree',\n templateUrl: './json-tree.component.html',\n styleUrl: './json-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n host: { class: 'block font-mono text-[12px] leading-5 select-text' },\n})\nexport class JsonTreeComponent {\n public readonly data = input.required<unknown>();\n public readonly expandDepth = input<number>(1);\n\n private collapsedPaths = new Set<string>();\n private userToggled = new Set<string>();\n\n protected isCollapsed(path: string, depth: number) {\n if (this.userToggled.has(path)) {\n return this.collapsedPaths.has(path);\n }\n return depth >= this.expandDepth();\n }\n\n protected toggle(path: string, depth: number) {\n this.userToggled.add(path);\n const currentlyCollapsed = this.isCollapsed(path, depth);\n if (currentlyCollapsed) {\n this.collapsedPaths.delete(path);\n } else {\n this.collapsedPaths.add(path);\n }\n }\n\n protected isObject(value: unknown) {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n }\n\n protected isArray(value: unknown) {\n return Array.isArray(value);\n }\n\n protected objectEntries(value: unknown) {\n if (!this.isObject(value)) return [];\n return Object.entries(value as Record<string, unknown>);\n }\n\n protected arrayItems(value: unknown) {\n return Array.isArray(value) ? value : [];\n }\n\n protected objectLength(value: unknown) {\n if (!this.isObject(value)) return 0;\n return Object.keys(value as Record<string, unknown>).length;\n }\n\n protected arrayLength(value: unknown) {\n return Array.isArray(value) ? value.length : 0;\n }\n\n protected formatPrimitive(value: unknown) {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') return JSON.stringify(value);\n return String(value);\n }\n\n protected primitiveClass(value: unknown) {\n if (value === null || value === undefined) return 'jt-null';\n if (typeof value === 'string') return 'jt-string';\n if (typeof value === 'number') return 'jt-number';\n if (typeof value === 'boolean') return 'jt-boolean';\n return '';\n }\n\n protected isContainer(value: unknown) {\n return this.isObject(value) || this.isArray(value);\n }\n\n protected parsed(value: unknown) {\n return this.deepParse(value);\n }\n\n private deepParse(value: unknown): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n return this.deepParse(JSON.parse(trimmed));\n } catch {\n return value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.deepParse(item));\n }\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = this.deepParse(val);\n }\n return result;\n }\n return value;\n }\n}\n","<!-- Entry point: parse and render the root value -->\n<ng-container\n *ngTemplateOutlet=\"valueTemplate; context: { $implicit: parsed(data()), path: '$', depth: 0 }\"\n/>\n\n<!-- Recursive value renderer -->\n<ng-template #valueTemplate let-value let-path=\"path\" let-depth=\"depth\">\n @if (isObject(value)) {\n @if (objectLength(value) === 0) {\n <span class=\"jt-bracket\">{{ '{' }}{{ '}' }}</span>\n } @else {\n <span class=\"jt-toggle\" (click)=\"toggle(path, depth); $event.stopPropagation()\" role=\"button\">\n <span class=\"jt-arrow\" [class.jt-arrow--collapsed]=\"isCollapsed(path, depth)\">&#9662;</span>\n <span class=\"jt-bracket\">{{ '{' }}</span>\n </span>\n @if (isCollapsed(path, depth)) {\n <span\n class=\"jt-collapsed-hint\"\n (click)=\"toggle(path, depth); $event.stopPropagation()\"\n role=\"button\"\n >{{ objectLength(value) }}\n {{ objectLength(value) === 1 ? 'property' : 'properties' }}</span\n ><span class=\"jt-bracket\">{{ '}' }}</span>\n } @else {\n <div class=\"jt-indent\">\n @for (entry of objectEntries(value); track entry[0]; let last = $last) {\n <div class=\"jt-line\">\n <span class=\"jt-key\">\"{{ entry[0] }}\"</span><span class=\"jt-colon\">: </span>\n @if (isContainer(entry[1])) {\n <ng-container\n *ngTemplateOutlet=\"\n valueTemplate;\n context: { $implicit: entry[1], path: path + '.' + entry[0], depth: depth + 1 }\n \"\n />\n } @else {\n <span [class]=\"primitiveClass(entry[1])\">{{ formatPrimitive(entry[1]) }}</span>\n }\n @if (!last) {\n <span class=\"jt-comma\">,</span>\n }\n </div>\n }\n </div>\n <span class=\"jt-bracket\">{{ '}' }}</span>\n }\n }\n } @else if (isArray(value)) {\n @if (arrayLength(value) === 0) {\n <span class=\"jt-bracket\">[]</span>\n } @else {\n <span class=\"jt-toggle\" (click)=\"toggle(path, depth); $event.stopPropagation()\" role=\"button\">\n <span class=\"jt-arrow\" [class.jt-arrow--collapsed]=\"isCollapsed(path, depth)\">&#9662;</span>\n <span class=\"jt-bracket\">[</span>\n </span>\n @if (isCollapsed(path, depth)) {\n <span\n class=\"jt-collapsed-hint\"\n (click)=\"toggle(path, depth); $event.stopPropagation()\"\n role=\"button\"\n >{{ arrayLength(value) }} {{ arrayLength(value) === 1 ? 'item' : 'items' }}</span\n ><span class=\"jt-bracket\">]</span>\n } @else {\n <div class=\"jt-indent\">\n @for (item of arrayItems(value); track $index; let last = $last) {\n <div class=\"jt-line\">\n @if (isContainer(item)) {\n <ng-container\n *ngTemplateOutlet=\"\n valueTemplate;\n context: { $implicit: item, path: path + '[' + $index + ']', depth: depth + 1 }\n \"\n />\n } @else {\n <span [class]=\"primitiveClass(item)\">{{ formatPrimitive(item) }}</span>\n }\n @if (!last) {\n <span class=\"jt-comma\">,</span>\n }\n </div>\n }\n </div>\n <span class=\"jt-bracket\">]</span>\n }\n }\n } @else {\n <span [class]=\"primitiveClass(value)\">{{ formatPrimitive(value) }}</span>\n }\n</ng-template>\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ToolUIPart } from 'ai';\nimport { HighlightPipe } from '../../pipes/highlight.pipe';\nimport { JsonTreeComponent } from '../json-tree/json-tree.component';\n\n@Component({\n selector: 'cortex-message-tool-call-part',\n templateUrl: './message-tool-call-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [HighlightPipe, NgClass, TranslatePipe, JsonTreeComponent],\n})\nexport class MessageToolCallPartComponent {\n private static readonly CODE_FIELDS: Record<string, string> = {\n code: 'javascript',\n query: 'cypher',\n };\n\n public readonly toolCallPart = input.required<ToolUIPart>();\n\n protected readonly codeSnippets = computed(() => {\n const inp = this.toolCallPart().input;\n if (!inp || typeof inp !== 'object') return [];\n\n const record = inp as Record<string, unknown>;\n const snippets: { key: string; lang: string; value: string }[] = [];\n\n for (const [key, lang] of Object.entries(MessageToolCallPartComponent.CODE_FIELDS)) {\n if (key in record && typeof record[key] === 'string') {\n snippets.push({\n key,\n lang,\n value: (record[key] as string).replace(/\\\\n/g, '\\n'),\n });\n }\n }\n return snippets;\n });\n\n protected readonly remainingInput = computed(() => {\n const inp = this.toolCallPart().input;\n if (!inp || typeof inp !== 'object') return inp;\n\n const record = inp as Record<string, unknown>;\n const codeKeys = Object.keys(MessageToolCallPartComponent.CODE_FIELDS);\n const remaining: Record<string, unknown> = {};\n let hasKeys = false;\n\n for (const [key, val] of Object.entries(record)) {\n if (!codeKeys.includes(key)) {\n remaining[key] = val;\n hasKeys = true;\n }\n }\n return hasKeys ? remaining : null;\n });\n\n protected toolName() {\n const type = this.toolCallPart().type;\n if (!type) return '';\n return type.startsWith('tool-') ? type.slice('tool-'.length) : type;\n }\n}\n","<details class=\"group w-full rounded-lg border border-slate-200 bg-slate-50 overflow-hidden\">\n <summary\n class=\"list-none [&::-webkit-details-marker]:hidden cursor-pointer select-none px-4 py-3 group-open:border-b group-open:border-slate-200\"\n >\n <div class=\"flex items-start gap-3\">\n <div\n class=\"shrink-0 mt-0.5 size-7 rounded bg-slate-800 text-white flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-4\" fill=\"none\">\n <path\n d=\"M6.5 6.5 3.75 10l2.75 3.5M13.5 6.5 16.25 10l-2.75 3.5M11.25 5.75 8.75 14.25\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex items-center gap-2\">\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex items-center gap-2 min-w-0\">\n <div\n class=\"font-medium text-slate-800 text-sm truncate\"\n [attr.title]=\"toolCallPart().title || null\"\n >\n {{ toolCallPart().title ?? 'Tool call' }}\n </div>\n @if (toolName()) {\n <span\n class=\"hidden sm:inline-flex items-center rounded bg-slate-200 px-1.5 py-0.5 text-[11px] font-medium text-slate-600 font-mono\"\n [attr.title]=\"toolCallPart().type || null\"\n >{{ toolName() }}</span\n >\n }\n </div>\n <div class=\"mt-0.5 text-[11px] text-slate-500 break-all\">\n <span class=\"font-medium text-slate-600\">ID</span>\n <span class=\"font-mono\"> {{ toolCallPart().toolCallId }}</span>\n @if (toolCallPart().providerExecuted) {\n <span class=\"ml-2 inline-flex items-center gap-1 text-emerald-700\">\n <span class=\"size-1.5 rounded-full bg-emerald-500\"></span>\n provider\n </span>\n }\n </div>\n </div>\n\n <div class=\"flex items-center gap-2\">\n <span\n class=\"inline-flex items-center gap-1.5 rounded px-2 py-1 text-[11px] font-medium border\"\n [ngClass]=\"{\n 'bg-emerald-50 text-emerald-700 border-emerald-200':\n toolCallPart().state === 'output-available',\n 'bg-red-50 text-red-700 border-red-200': toolCallPart().state === 'output-error',\n 'bg-slate-100 text-slate-600 border-slate-200':\n toolCallPart().state === 'output-denied',\n 'bg-violet-50 text-violet-700 border-violet-200':\n toolCallPart().state === 'approval-requested' ||\n toolCallPart().state === 'approval-responded',\n 'bg-amber-50 text-amber-700 border-amber-200':\n toolCallPart().state === 'input-streaming' ||\n toolCallPart().state === 'input-available',\n }\"\n >\n @switch (toolCallPart().state) {\n @case ('input-streaming') {\n <span class=\"size-1.5 rounded-full bg-amber-500 animate-pulse\"></span>\n Calling\n }\n @case ('input-available') {\n <span class=\"size-1.5 rounded-full bg-amber-500\"></span> Input ready\n }\n @case ('approval-requested') {\n <span class=\"size-1.5 rounded-full bg-violet-500 animate-pulse\"></span>\n Needs approval\n }\n @case ('approval-responded') {\n @if (toolCallPart().approval?.approved) {\n <span class=\"size-1.5 rounded-full bg-emerald-500\"></span> Approved\n } @else {\n <span class=\"size-1.5 rounded-full bg-slate-500\"></span> Responded\n }\n }\n @case ('output-available') {\n <span class=\"size-1.5 rounded-full bg-emerald-500\"></span>\n {{ 'translate_completed' | translate }}\n }\n @case ('output-error') {\n <span class=\"size-1.5 rounded-full bg-red-500\"></span> Error\n }\n @case ('output-denied') {\n <span class=\"size-1.5 rounded-full bg-slate-500\"></span> Denied\n }\n }\n </span>\n\n <span\n class=\"inline-flex size-6 items-center justify-center rounded text-slate-400 transition group-open:rotate-180\"\n aria-hidden=\"true\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"m5.75 8.25 4.25 4.25 4.25-4.25\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </div>\n </div>\n </div>\n </div>\n </summary>\n\n <div class=\"bg-white px-4 pb-4 pt-3\">\n <div class=\"grid gap-3\">\n @for (snippet of codeSnippets(); track snippet.key) {\n <div class=\"rounded-lg border border-slate-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-slate-200 bg-slate-50\"\n >\n <div class=\"text-[11px] font-medium text-slate-600\">\n {{ snippet.key }}\n </div>\n <div class=\"text-[11px] text-slate-400 font-mono\">\n {{ snippet.lang }}\n </div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"m-0 max-h-80 overflow-auto p-3 text-[12px] leading-5 font-mono whitespace-pre wrap-break-word\"\n ><code class=\"hljs\" [innerHTML]=\"snippet.value | highlight : snippet.lang\"></code></pre>\n </div>\n }\n\n @if (remainingInput(); as remaining) {\n <div class=\"rounded-lg border border-slate-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-slate-200 bg-slate-50\"\n >\n <div class=\"text-[11px] font-medium text-slate-600\">Input</div>\n <div class=\"text-[11px] text-slate-400 font-mono\">json</div>\n </div>\n <div dir=\"ltr\" class=\"max-h-64 overflow-auto p-3\">\n <cortex-json-tree [data]=\"remaining\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-available') {\n <div class=\"rounded-lg border border-emerald-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-emerald-200 bg-emerald-50\"\n >\n <div class=\"text-[11px] font-medium text-emerald-700\">Output</div>\n <div class=\"text-[11px] text-emerald-600 font-mono\">json</div>\n </div>\n <div dir=\"ltr\" class=\"max-h-64 overflow-auto p-3\">\n <cortex-json-tree [data]=\"toolCallPart().output\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-error') {\n <div class=\"rounded-lg border border-red-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-red-200 bg-red-50\"\n >\n <div class=\"text-[11px] font-medium text-red-700\">Error</div>\n <div class=\"text-[11px] text-red-600 font-mono\">text</div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"m-0 max-h-64 overflow-auto p-3 text-[12px] leading-5 font-mono text-red-800 whitespace-pre-wrap wrap-break-word\"\n >{{ toolCallPart().errorText }}</pre\n >\n </div>\n }\n\n @if (toolCallPart().state === 'output-denied') {\n <div class=\"rounded-lg border border-slate-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-slate-200 bg-slate-50\"\n >\n <div class=\"text-[11px] font-medium text-slate-600\">Denied</div>\n <div class=\"text-[11px] text-slate-500 font-mono\">approval</div>\n </div>\n <div class=\"p-3 text-[12px] text-slate-700\">\n Tool execution was denied.\n @if (toolCallPart().approval?.reason) {\n <div class=\"mt-2 rounded bg-slate-50 border border-slate-200 p-2\">\n <div class=\"text-[11px] font-medium text-slate-600\">Reason</div>\n <div class=\"mt-1 font-mono text-[12px] text-slate-700 wrap-break-word\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-requested') {\n <div class=\"rounded-lg border border-violet-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-violet-200 bg-violet-50\"\n >\n <div class=\"text-[11px] font-medium text-violet-700\">Approval requested</div>\n <div class=\"text-[11px] text-violet-600 font-mono\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"p-3 text-[12px] text-violet-800\">\n Waiting for approval to execute this tool.\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-responded') {\n <div class=\"rounded-lg border border-violet-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-violet-200 bg-violet-50\"\n >\n <div class=\"text-[11px] font-medium text-violet-700\">Approval response</div>\n <div class=\"text-[11px] text-violet-600 font-mono\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"p-3 text-[12px] text-violet-800\">\n @if (toolCallPart().approval?.approved) {\n Approved.\n } @else {\n Response received.\n }\n @if (toolCallPart().approval?.reason) {\n <div class=\"mt-2 rounded bg-violet-50 border border-violet-200 p-2\">\n <div class=\"text-[11px] font-medium text-violet-700\">Reason</div>\n <div class=\"mt-1 font-mono text-[12px] text-violet-800 wrap-break-word\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</details>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n signal,\n forwardRef,\n Signal,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormBuilder,\n FormControl,\n NG_VALUE_ACCESSOR,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { ToolUIPart, UIMessage } from 'ai';\nimport { finalize } from 'rxjs';\nimport { fromPromise } from 'rxjs/internal/observable/innerFrom';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { CortexChatService } from '../../services/cortex-chat.service';\nimport { CORTEX_CLIENT_CONFIG } from '../../config';\n\ntype InputFile = {\n name: string;\n bytes: string;\n};\n\n@Component({\n selector: 'cortex-message-capture-files-part',\n templateUrl: './message-capture-files-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ReactiveFormsModule, forwardRef(() => FileInputComponent), TranslatePipe],\n styles: [\n `\n :host {\n @apply w-full block;\n }\n `,\n ],\n})\nexport class MessageCaptureFilesPartComponent {\n public readonly message = input.required<UIMessage>();\n public readonly toolPart = input.required<ToolUIPart>();\n public readonly data = computed(\n () =>\n this.toolPart().input as {\n files: {\n label: string;\n id: string;\n }[];\n },\n );\n\n protected readonly isLoading = signal(false);\n\n protected readonly outputData = computed(() => {\n const raw = this.toolPart().output;\n if (!raw) return null;\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n return parsed as {\n status: 'success' | 'canceled';\n message?: string;\n result?: { id: string; uploadId: string }[];\n };\n });\n\n protected readonly form = computed(() => {\n const form = this.fb.group({\n files: this.fb.array(\n this.data().files.map((x) =>\n this.fb.group({\n id: new FormControl(x.id, { nonNullable: true, validators: [Validators.required] }),\n file: new FormControl(null as unknown as InputFile, {\n nonNullable: true,\n validators: [Validators.required],\n }),\n }),\n ),\n ),\n });\n\n if (this.toolPart().output) {\n form.disable();\n }\n\n return form;\n });\n\n private readonly fb = inject(FormBuilder);\n private readonly chatService = inject(CortexChatService);\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n\n protected async submit() {\n if (this.form().invalid || this.isLoading()) return;\n\n this.isLoading.set(true);\n const { files } = this.form().getRawValue();\n\n const baseUrl = this.config.transport.baseUrl;\n const base = typeof baseUrl === 'string' ? baseUrl : (baseUrl as Signal<string>)();\n const url = base.replace(/\\/$/, '') + '/files';\n\n fromPromise(\n (async () => {\n const headers = await Promise.resolve(this.config.transport.getAuthHeaders());\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n files,\n toolCallId: this.toolPart().toolCallId,\n message: this.message(),\n }),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n return res.json();\n })(),\n )\n .pipe(finalize(() => this.isLoading.set(false)))\n .subscribe((result) => {\n this.chatService.chat()?.addToolOutput({\n tool: 'captureFiles',\n toolCallId: this.toolPart().toolCallId,\n output: {\n status: 'success',\n result,\n },\n });\n });\n }\n\n protected async downloadFile(uploadId: string) {\n const baseUrl = this.config.transport.baseUrl;\n const base = typeof baseUrl === 'string' ? baseUrl : (baseUrl as Signal<string>)();\n const url = base.replace(/\\/$/, '') + '/files/' + uploadId;\n const headers = await Promise.resolve(this.config.transport.getAuthHeaders());\n\n const response = await fetch(url, { headers });\n const disposition = response.headers.get('Content-Disposition');\n const name = disposition?.match(/filename=\"?([^\";\\n]+)\"?/)?.[1] ?? uploadId;\n const blob = await response.blob();\n const blobUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = blobUrl;\n a.download = name;\n a.click();\n URL.revokeObjectURL(blobUrl);\n }\n\n protected cancel() {\n this.chatService.chat()?.addToolOutput({\n tool: 'captureFiles',\n toolCallId: this.toolPart().toolCallId,\n output: {\n status: 'canceled',\n message: 'User canceled upload',\n },\n });\n }\n}\n\n@Component({\n selector: 'cortex-file-input',\n template: `<div\n class=\"flex w-full cursor-pointer items-center rounded-lg border border-slate-300 bg-slate-50 transition hover:border-slate-400 focus-within:ring-2 focus-within:ring-slate-300\"\n >\n <button\n type=\"button\"\n (click)=\"fileInput.click()\"\n class=\"m-1 shrink-0 cursor-pointer rounded-md border-0 bg-slate-800 px-3 py-1.5 text-[11px] font-semibold tracking-wide text-slate-100 hover:bg-slate-700\"\n >\n {{ 'translate_choose_file' | translate }}\n </button>\n <span class=\"truncate px-3 text-[12px] text-slate-600\">{{\n value()?.name ?? ('translate_no_file_chosen' | translate)\n }}</span>\n <input #fileInput (change)=\"loadFile($event)\" type=\"file\" class=\"hidden\" />\n </div>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [TranslatePipe],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: forwardRef(() => FileInputComponent),\n },\n ],\n})\nexport class FileInputComponent implements ControlValueAccessor {\n public allowedMimeTypes = input('*/*');\n\n protected readonly value = signal<InputFile | undefined>(undefined);\n protected readonly isDisabled = signal<boolean>(false);\n protected onTouch?: () => void;\n protected readonly isProcessing = signal<boolean>(false);\n\n private onChange?: (value?: InputFile) => void;\n\n writeValue(value?: InputFile) {\n this.value.set(value);\n }\n\n registerOnChange(fn: (value?: InputFile) => void) {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void) {\n this.onTouch = fn;\n }\n\n setDisabledState(isDisabled: boolean) {\n this.isDisabled.set(isDisabled);\n }\n\n protected async loadFile(event: Event) {\n const fileInput = event.target as HTMLInputElement;\n if (fileInput.files?.length !== 1) return;\n const inputFile = fileInput.files[0];\n const result = await convertFileToBase64(inputFile);\n this.updateValue({\n name: result.name,\n bytes: result.bytes,\n });\n }\n\n protected updateValue(value: InputFile) {\n this.value.set(value);\n this.onChange?.(value);\n }\n}\n\nasync function convertFileToBase64(file: File) {\n return new Promise<{\n name: string;\n bytes: string;\n mimeType: string;\n format: string;\n readerResult: string | ArrayBuffer | null;\n }>((resolve, reject) => {\n const tokens = file.name.split('.');\n const format = tokens.length > 1 ? tokens[tokens.length - 1] : '';\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => {\n const parts = (reader.result as string).split(',');\n const mimeType = parts[0].replace('data:', '').replace(';base64', '');\n resolve({\n name: file.name,\n bytes: parts[1],\n mimeType,\n format,\n readerResult: reader.result,\n });\n };\n reader.onerror = () => reject();\n });\n}\n","@if (outputData(); as output) {\n <!-- ── Result state ── -->\n @if (output.status === 'success') {\n <div\n class=\"overflow-hidden rounded-2xl border border-emerald-200 bg-linear-to-b from-emerald-50/80 to-white\"\n >\n <div class=\"flex items-center gap-3 px-4 py-3 sm:px-5\">\n <div\n class=\"inline-flex size-8 shrink-0 items-center justify-center rounded-lg border border-emerald-200 bg-emerald-100 text-emerald-600\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-4\" fill=\"none\">\n <path\n d=\"M5.5 10.5 L8.5 13.5 L14.5 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n <div class=\"min-w-0\">\n <h3 class=\"text-[13px] font-semibold tracking-tight text-emerald-800\">\n {{ 'translate_files_attached' | translate: { count: data().files.length } }}\n </h3>\n </div>\n </div>\n\n <div class=\"border-t border-emerald-100 px-4 py-2.5 sm:px-5\">\n <ul class=\"flex flex-wrap gap-2\">\n @for (file of outputData()!.result!; track file.uploadId) {\n <li>\n <button\n type=\"button\"\n (click)=\"downloadFile(file.uploadId)\"\n class=\"inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-emerald-100 bg-white px-2.5 py-1.5 text-[12px] font-medium text-emerald-700 shadow-xs transition-all hover:border-emerald-200 hover:bg-emerald-50 hover:shadow-sm active:scale-[0.97]\"\n >\n <svg viewBox=\"0 0 16 16\" class=\"size-3.5 shrink-0 text-emerald-400\" fill=\"none\">\n <path\n d=\"M4 1.5h5.172a2 2 0 0 1 1.414.586l2.328 2.328a2 2 0 0 1 .586 1.414V12.5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n <path\n d=\"M9.5 1.5v2a2 2 0 0 0 2 2h2\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n </svg>\n <span class=\"truncate max-w-[180px]\">{{ data().files[$index].label }}</span>\n <svg viewBox=\"0 0 16 16\" class=\"size-3 shrink-0 text-emerald-300\" fill=\"none\">\n <path\n d=\"M8 3v7m0 0L5.5 7.5M8 10l2.5-2.5M3 13h10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </li>\n }\n </ul>\n </div>\n </div>\n } @else {\n <!-- Canceled state -->\n <div class=\"flex justify-center\">\n <div\n class=\"inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-slate-50 px-4 py-2.5\"\n >\n <div\n class=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-slate-200 bg-slate-100 text-slate-400\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-3\" fill=\"none\">\n <path d=\"M6 10h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </div>\n <span class=\"text-[13px] font-medium text-slate-400\">{{\n 'translate_file_upload_skipped' | translate\n }}</span>\n </div>\n </div>\n }\n} @else {\n <!-- ── Upload form ── -->\n <form [formGroup]=\"form()\" class=\"w-full\">\n @if (data().files.length === 1) {\n <!-- Single file: minimal inline -->\n <fieldset [formArray]=\"form().controls.files\">\n <div [formGroupName]=\"0\" class=\"rounded-xl border border-slate-200 bg-slate-50 p-3\">\n <label for=\"capture-file-0\" class=\"mb-1.5 block text-[12px] text-slate-500\">\n {{ data().files[0].label }}\n </label>\n <input hidden formControlName=\"id\" />\n <div class=\"flex items-center gap-2\">\n <cortex-file-input id=\"capture-file-0\" formControlName=\"file\" class=\"min-w-0 flex-1\" />\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"shrink-0 text-[12px] font-medium text-slate-400 transition-colors hover:text-slate-600\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"inline-flex shrink-0 items-center rounded-md bg-slate-800 px-3 py-1.5 text-[12px] font-medium text-slate-100 transition-colors hover:bg-slate-700 active:bg-slate-900 disabled:cursor-not-allowed disabled:bg-slate-300\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"mr-1.5 size-3 animate-spin\" viewBox=\"0 0 16 16\" fill=\"none\">\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n class=\"opacity-25\"\n />\n <path\n d=\"M14 8a6 6 0 0 0-6-6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ 'translate_uploading' | translate }}\n } @else {\n {{ 'translate_submit' | translate }}\n }\n </button>\n </div>\n </div>\n </fieldset>\n } @else {\n <!-- Multi-file: full form -->\n <div\n class=\"overflow-hidden rounded-2xl border border-slate-200 bg-gradient-to-b from-white to-slate-50\"\n >\n <div class=\"border-b border-slate-200 bg-white/85 px-4 py-3 sm:px-5\">\n <div class=\"flex items-start gap-3\">\n <div\n class=\"mt-0.5 inline-flex size-8 shrink-0 items-center justify-center rounded-lg border border-slate-200 bg-slate-100 text-slate-600\"\n aria-hidden=\"true\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-4\" fill=\"none\">\n <path\n d=\"M4 13.5a3.5 3.5 0 0 1-.5-6.97 5.002 5.002 0 0 1 9.78-1.03A4.5 4.5 0 0 1 15.5 14\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M10 10v7m0-7-2.5 2.5M10 10l2.5 2.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n\n <div class=\"min-w-0\">\n <h3 class=\"text-[13px] font-semibold tracking-tight text-slate-800\">\n {{ 'translate_attach_requested_files' | translate }}\n </h3>\n <p class=\"mt-0.5 text-[11px] text-slate-500\">\n {{ 'translate_n_files_required' | translate: { count: data().files.length } }}\n </p>\n </div>\n </div>\n </div>\n\n <fieldset [formArray]=\"form().controls.files\" class=\"grid gap-3 p-4 sm:p-5\">\n @for (file of form().controls.files.value; track $index) {\n <div\n [formGroupName]=\"$index\"\n class=\"rounded-xl border border-slate-200 bg-white p-3 transition-colors hover:border-slate-300\"\n >\n <div class=\"mb-2 flex items-center justify-between gap-2\">\n <label\n [for]=\"'capture-file-' + $index\"\n class=\"block text-[12px] font-medium leading-none text-slate-700\"\n >\n {{ data().files[$index].label }}\n </label>\n <span\n class=\"inline-flex items-center rounded border border-slate-200 bg-slate-50 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-slate-500\"\n >\n {{ 'translate_required' | translate }}\n </span>\n </div>\n\n <input hidden formControlName=\"id\" />\n <cortex-file-input [id]=\"'capture-file-' + $index\" formControlName=\"file\" />\n </div>\n }\n </fieldset>\n\n <div\n class=\"flex items-center justify-end gap-2 border-t border-slate-200 bg-white/90 px-4 py-3 sm:px-5\"\n >\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"inline-flex items-center rounded-md border border-slate-300 bg-white px-3 py-1.5 text-[12px] font-medium text-slate-600 transition-colors hover:bg-slate-50 active:bg-slate-100\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"inline-flex items-center rounded-md bg-slate-800 px-3 py-1.5 text-[12px] font-medium text-slate-100 transition-colors hover:bg-slate-700 active:bg-slate-900 disabled:cursor-not-allowed disabled:bg-slate-300\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"mr-1.5 size-3 animate-spin\" viewBox=\"0 0 16 16\" fill=\"none\">\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n class=\"opacity-25\"\n />\n <path\n d=\"M14 8a6 6 0 0 0-6-6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ 'translate_uploading' | translate }}\n } @else {\n {{ 'translate_submit_files' | translate }}\n }\n </button>\n </div>\n </div>\n }\n </form>\n}\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ToolUIPart, UIMessage } from 'ai';\nimport { MessageCaptureFilesPartComponent } from '../message-capture-file-part/message-capture-files-part.component';\nimport { CORTEX_CLIENT_CONFIG } from '../../config';\n\nconst STATUS_COUNT = 10;\n\n@Component({\n selector: 'cortex-message-tool-call-animated',\n templateUrl: './message-tool-call-animated.component.html',\n styleUrl: './message-tool-call-animated.component.scss',\n imports: [NgClass, MessageCaptureFilesPartComponent, TranslatePipe],\n host: { class: 'block w-full' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MessageToolCallAnimatedComponent {\n public readonly message = input.required<UIMessage>();\n public readonly toolCallPart = input.required<ToolUIPart>();\n\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n\n protected readonly customComponent = computed(() => {\n const toolName = this.toolCallPart().type;\n const name = toolName?.startsWith('tool-') ? toolName.slice('tool-'.length) : toolName;\n return name ? (this.config.toolComponents?.[name] ?? null) : null;\n });\n\n protected readonly animState = computed(() => {\n const state = this.toolCallPart().state;\n switch (state) {\n case 'input-streaming':\n return 'starting';\n case 'input-available':\n case 'approval-requested':\n case 'approval-responded':\n return 'processing';\n case 'output-available':\n return 'complete';\n case 'output-error':\n return 'error';\n case 'output-denied':\n return 'denied';\n default:\n return 'processing';\n }\n });\n\n protected readonly isActive = computed(() => {\n const s = this.animState();\n return s === 'starting' || s === 'processing';\n });\n\n protected readonly displayTitleKey = computed(() => {\n const state = this.animState();\n switch (state) {\n case 'starting':\n case 'processing':\n return `translate_tool_status_${this.stableIndex()}`;\n case 'complete':\n return `translate_tool_done_${this.stableIndex()}`;\n case 'error':\n return 'translate_tool_error';\n case 'denied':\n return 'translate_tool_denied';\n default:\n return `translate_tool_status_${this.stableIndex()}`;\n }\n });\n\n private readonly stableIndex = computed(() => {\n const id = this.toolCallPart().toolCallId ?? '';\n let hash = 0;\n for (let i = 0; i < id.length; i++) {\n hash = (hash * 31 + id.charCodeAt(i)) | 0;\n }\n return Math.abs(hash) % STATUS_COUNT;\n });\n}\n","@if (customComponent(); as custom) {\n <ng-container\n *ngComponentOutlet=\"custom; inputs: { toolCallPart: toolCallPart(), message: message() }\"\n />\n} @else {\n @switch (toolCallPart().type) {\n @case ('tool-captureFiles') {\n <cortex-message-capture-files-part [toolPart]=\"toolCallPart()\" [message]=\"message()\" />\n }\n @default {\n @let state = animState();\n @let active = isActive();\n\n <div class=\"flex justify-center\">\n <div\n class=\"inline-flex items-center gap-2.5 py-2.5 px-4 rounded-lg border relative overflow-hidden transition-colors duration-300\"\n [ngClass]=\"{\n 'border-indigo-200 bg-indigo-50': active,\n 'border-emerald-200 bg-emerald-50': state === 'complete',\n 'border-red-200 bg-red-50': state === 'error',\n 'border-slate-200 bg-slate-50 opacity-60': state === 'denied',\n }\"\n >\n <!-- Icon box -->\n <div\n class=\"relative size-6 flex items-center justify-center rounded-md border shrink-0 transition-colors duration-300\"\n [ngClass]=\"{\n 'bg-indigo-100 border-indigo-200': active,\n 'bg-emerald-100 border-emerald-200': state === 'complete',\n 'bg-red-100 border-red-200': state === 'error',\n 'bg-slate-100 border-slate-200': state === 'denied',\n }\"\n >\n <!-- Spinner -->\n <div\n class=\"absolute size-3 border-[1.5px] border-indigo-200 border-t-indigo-500 rounded-full animate-spin transition-opacity duration-200\"\n [ngClass]=\"active ? 'opacity-100' : 'opacity-0'\"\n ></div>\n <!-- Check -->\n <svg\n class=\"absolute size-3 transition-all duration-200\"\n [ngClass]=\"\n state === 'complete'\n ? 'opacity-100 scale-100 text-emerald-600'\n : 'opacity-0 scale-[0.6]'\n \"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M5.5 10.5 L8.5 13.5 L14.5 7\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <!-- Error -->\n <svg\n class=\"absolute size-3 transition-all duration-200\"\n [ngClass]=\"\n state === 'error' ? 'opacity-100 scale-100 text-red-600' : 'opacity-0 scale-[0.6]'\n \"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M6.5 6.5 L13.5 13.5 M13.5 6.5 L6.5 13.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n <!-- Denied -->\n <svg\n class=\"absolute size-3 transition-all duration-200\"\n [ngClass]=\"\n state === 'denied'\n ? 'opacity-100 scale-100 text-slate-400'\n : 'opacity-0 scale-[0.6]'\n \"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M6 10 L14 10\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n\n <!-- Title -->\n <span\n class=\"text-[13px] font-medium whitespace-nowrap overflow-hidden text-ellipsis transition-colors duration-300\"\n [ngClass]=\"{\n 'text-indigo-700': active,\n 'text-emerald-700': state === 'complete',\n 'text-red-600': state === 'error',\n 'text-slate-400': state === 'denied',\n }\"\n >\n {{ displayTitleKey() | translate }}\n </span>\n\n <!-- Bottom bar -->\n <div class=\"absolute bottom-0 inset-x-0 h-0.5 overflow-hidden\">\n <div\n class=\"h-full w-full origin-left\"\n [ngClass]=\"{\n 'bg-indigo-400 animate-bar-slide': active,\n 'bg-emerald-400 animate-bar-fill': state === 'complete',\n 'bg-red-400 animate-bar-fill': state === 'error',\n 'opacity-0': state === 'denied',\n }\"\n ></div>\n </div>\n </div>\n </div>\n }\n }\n}\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ReasoningUIPart } from 'ai';\n\n@Component({\n selector: 'cortex-message-reasoning-animated',\n templateUrl: './message-reasoning-animated.component.html',\n styleUrl: './message-reasoning-animated.component.scss',\n imports: [NgClass, TranslatePipe],\n host: { class: 'flex justify-center' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MessageReasoningAnimatedComponent {\n public readonly reasoningPart = input.required<ReasoningUIPart>();\n}\n","@let p = reasoningPart();\n@let streaming = p.state === 'streaming';\n\n<div\n class=\"inline-flex items-center gap-2.5 py-2 pl-3 pr-4 rounded-lg border transition-colors duration-300\"\n [ngClass]=\"streaming ? 'border-indigo-200 bg-indigo-50' : 'border-slate-200 bg-slate-50'\"\n>\n <div class=\"flex items-center gap-1\">\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n ></span>\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n [style.animation-delay]=\"streaming ? '200ms' : '0ms'\"\n ></span>\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n [style.animation-delay]=\"streaming ? '400ms' : '0ms'\"\n ></span>\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n [style.animation-delay]=\"streaming ? '600ms' : '0ms'\"\n ></span>\n </div>\n\n <span\n class=\"text-[13px] font-medium transition-colors duration-300\"\n [ngClass]=\"streaming ? 'text-indigo-600' : 'text-slate-400'\"\n >\n {{ streaming ? ('translate_thinking' | translate) : ('translate_reasoned' | translate) }}\n </span>\n</div>\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { UIDataTypes, UIMessage, UIMessagePart, UITools, isStaticToolUIPart } from 'ai';\nimport { MessageTextPartComponent } from '../message-text-part/message-text-part.component';\nimport { MessageReasoningPartComponent } from '../message-reasoning-part/message-reasoning-part.component';\nimport { MessageToolCallPartComponent } from '../message-tool-call-part/message-tool-call-part.component';\nimport { MessageToolCallAnimatedComponent } from '../message-tool-call-animated/message-tool-call-animated.component';\nimport { MessageReasoningAnimatedComponent } from '../message-reasoning-animated/message-reasoning-animated.component';\nimport { CORTEX_CLIENT_CONFIG } from '../../config';\n\n@Component({\n selector: 'cortex-message-part',\n templateUrl: './message-part.component.html',\n imports: [\n MessageTextPartComponent,\n MessageReasoningPartComponent,\n MessageToolCallPartComponent,\n MessageToolCallAnimatedComponent,\n MessageReasoningAnimatedComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.animate-part-enter]': 'animate()',\n },\n styles: [\n `\n :host {\n @apply empty:hidden block;\n }\n\n :host.animate-part-enter {\n animation: partFadeInUp 0.2s cubic-bezier(0.34, 1.56, 0.64, 1) both;\n }\n\n @keyframes partFadeInUp {\n from {\n opacity: 0;\n transform: translateY(30px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n `,\n ],\n})\nexport class MessagePartComponent {\n public readonly message = input.required<UIMessage>();\n public readonly part = input.required<UIMessagePart<UIDataTypes, UITools>>();\n public readonly debugMode = input<boolean>(false);\n public readonly animate = input<boolean>(false);\n\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n\n protected readonly isStaticToolUIPart = isStaticToolUIPart;\n\n protected readonly customToolComponent = computed(() => {\n const p = this.part();\n if (!isStaticToolUIPart(p)) return null;\n const toolName = p.type?.startsWith('tool-') ? p.type.slice('tool-'.length) : p.type;\n return toolName ? (this.config.toolComponents?.[toolName] ?? null) : null;\n });\n}\n","@let myPart = part();\n@switch (myPart.type) {\n @case ('text') {\n <cortex-message-text-part [textPart]=\"myPart\" [role]=\"message().role\" />\n }\n @case ('reasoning') {\n @if (debugMode()) {\n <cortex-message-reasoning-part [reasoningPart]=\"myPart\" />\n } @else {\n <cortex-message-reasoning-animated [reasoningPart]=\"myPart\" />\n }\n }\n @default {\n @if (isStaticToolUIPart(myPart)) {\n @if (!debugMode() || customToolComponent()) {\n <cortex-message-tool-call-animated [toolCallPart]=\"myPart\" [message]=\"message()\" />\n } @else {\n <cortex-message-tool-call-part [toolCallPart]=\"myPart\" />\n }\n } @else {\n <p class=\"text-center text-xs text-slate-400\">Unhandled type: {{ part().type }}</p>\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, effect, input, signal } from '@angular/core';\nimport { generateId, UIDataTypes, UIMessage, UIMessagePart, UITools } from 'ai';\nimport { MessagePartComponent } from '../message-part/message-part.component';\n\ntype TrackedPart = UIMessagePart<UIDataTypes, UITools> & { __id: string };\n\n@Component({\n selector: 'cortex-message',\n templateUrl: './message.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MessagePartComponent],\n styles: [\n `\n :host {\n @apply empty:hidden;\n }\n `,\n ],\n})\nexport class MessageComponent {\n public readonly message = input.required<UIMessage>();\n public readonly debugMode = input<boolean>(false);\n public readonly animate = input<boolean>(false);\n\n protected readonly visibleParts = computed(() =>\n this.parts().filter((x) => x.type !== 'step-start'),\n );\n private readonly parts = signal<UIMessagePart<UIDataTypes, UITools>[]>([]);\n\n constructor() {\n effect(() => {\n const parts = this.message().parts;\n\n this.parts.set(parts);\n\n const originalPush = parts.push;\n\n parts.push = (...items) => {\n const newParts = items as unknown as TrackedPart[];\n\n newParts.forEach((x) => (x.__id = generateId()));\n\n this.parts.update((x) => [...x, ...newParts]);\n\n newParts.forEach((part) => {\n Object.keys(part).forEach((prop) => {\n let value = part[prop as keyof typeof part];\n Object.defineProperty(part, prop, {\n get: () => value,\n set: (newValue) => {\n value = newValue;\n this.parts.update((existingParts) => {\n return existingParts.map((x) => {\n return (x as TrackedPart).__id === part.__id ? { ...x, [prop]: newValue } : x;\n });\n });\n },\n configurable: true,\n });\n });\n });\n\n return originalPush.apply(parts, newParts);\n };\n });\n }\n}\n","@if (visibleParts().length) {\n <div class=\"w-full flex flex-col gap-2\">\n @for (part of visibleParts(); track $index) {\n <cortex-message-part\n [part]=\"part\"\n [message]=\"message()\"\n [debugMode]=\"debugMode()\"\n [animate]=\"animate()\"\n />\n }\n </div>\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n effect,\n ElementRef,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CortexChatService } from '../../services/cortex-chat.service';\nimport { MessageComponent } from '../message/message.component';\n\n@Component({\n selector: 'cortex-message-list',\n templateUrl: './message-list.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MessageComponent],\n})\nexport class MessageListComponent implements AfterViewInit {\n public readonly debugMode = input<boolean>(false);\n private readonly messagesContainer = viewChild<ElementRef>('messagesContainer');\n private shouldScrollToBottom = true;\n private isNearBottom = true;\n\n protected readonly animateNewParts = signal(false);\n\n constructor(\n protected readonly chatService: CortexChatService,\n destroyRef: DestroyRef,\n ) {\n this.scrollToBottom();\n\n effect(() => {\n this.chatService.chat()?.messages;\n\n if (!this.shouldScrollToBottom && !this.isNearBottom) {\n return;\n }\n\n queueMicrotask(() => {\n this.scrollToBottom();\n this.shouldScrollToBottom = false;\n });\n });\n\n chatService.events$.pipe(takeUntilDestroyed(destroyRef)).subscribe((event) => {\n if (event === 'onThreadSelected') {\n this.animateNewParts.set(false);\n this.shouldScrollToBottom = true;\n queueMicrotask(() => this.animateNewParts.set(true));\n }\n if (event === 'onSend') this.shouldScrollToBottom = true;\n });\n }\n\n ngAfterViewInit() {\n queueMicrotask(() => {\n this.scrollToBottom();\n this.shouldScrollToBottom = false;\n this.animateNewParts.set(true);\n });\n }\n\n protected onScroll() {\n const el = this.messagesContainer()?.nativeElement;\n if (!el) return;\n this.isNearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n }\n\n private scrollToBottom() {\n const el = this.messagesContainer()?.nativeElement;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }\n}\n","<div\n class=\"h-full overflow-y-auto w-full flex flex-col gap-2 p-4\"\n #messagesContainer\n (scroll)=\"onScroll()\"\n>\n @for (message of chatService.chat()?.messages; track message.id) {\n <cortex-message [message]=\"message\" [debugMode]=\"debugMode()\" [animate]=\"animateNewParts()\" />\n }\n</div>\n","import { TranslateLoader } from '@ngx-translate/core';\nimport { Observable, of } from 'rxjs';\nimport en from './en.json';\nimport ar from './ar.json';\n\nconst translations: Record<string, Record<string, string>> = { en, ar };\n\nexport class CortexClientTranslateLoader implements TranslateLoader {\n getTranslation(lang: string): Observable<Record<string, string>> {\n return of(translations[lang] ?? translations['en']);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n effect,\n inject,\n Injectable,\n Injector,\n input,\n model,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { NgClass } from '@angular/common';\nimport {\n provideTranslateLoader,\n provideTranslateService,\n TranslatePipe,\n TranslateService,\n} from '@ngx-translate/core';\nimport { CortexChatService } from '../../services/cortex-chat.service';\nimport { Thread } from '../../services/cortex-chat.service';\nimport { MessageListComponent } from '../message-list/message-list.component';\nimport { CORTEX_CLIENT_CONFIG, CortexClientConfig, CortexClientTheme } from '../../config';\nimport { CortexClientWebSocketService } from '../../services/cortex-websocket.service';\nimport { CortexClientTranslateLoader } from '../../i18n/translate-loader';\n\n@Injectable()\nclass CortexClientConfigRef {\n config!: CortexClientConfig;\n}\n\n@Component({\n selector: 'cortex-chat-widget',\n templateUrl: './chat-widget.component.html',\n styleUrl: './chat-widget.component.scss',\n imports: [NgClass, MessageListComponent, FormsModule, TranslatePipe],\n providers: [\n CortexClientConfigRef,\n {\n provide: CORTEX_CLIENT_CONFIG,\n useFactory: () => inject(CortexClientConfigRef).config,\n },\n CortexChatService,\n CortexClientWebSocketService,\n ...provideTranslateService({\n fallbackLang: 'en',\n loader: provideTranslateLoader(CortexClientTranslateLoader),\n }),\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'block',\n '[style.--cortex-primary-color]': 'theme()?.primaryColor',\n '[style.--cortex-bg-color]': 'theme()?.backgroundColor',\n '[style.--cortex-surface-color]': 'theme()?.surfaceColor',\n '[style.--cortex-text-color]': 'theme()?.textColor',\n '[style.--cortex-border-radius]': 'theme()?.borderRadius',\n },\n})\nexport class CortexChatWidgetComponent {\n public readonly config = input.required<CortexClientConfig>();\n\n protected readonly text = model<string>('');\n protected readonly debugMode = signal(false);\n protected readonly screen = signal<'threads' | 'chat'>('threads');\n protected readonly theme = signal<CortexClientTheme | undefined>(undefined);\n\n protected chatService!: CortexChatService;\n\n private readonly configRef = inject(CortexClientConfigRef);\n private readonly injector = inject(Injector);\n\n ngOnInit() {\n this.configRef.config = this.config();\n this.theme.set(this.config().theme);\n\n this.chatService = this.injector.get(CortexChatService);\n\n const translateService = this.injector.get(TranslateService);\n translateService.use(this.config().locale());\n\n effect(\n () => {\n translateService.use(this.config().locale());\n },\n { injector: this.injector },\n );\n }\n\n protected toggleDebugMode() {\n this.debugMode.update((v) => !v);\n }\n\n protected selectThread(thread: Thread) {\n this.chatService.selectThread(thread).subscribe();\n this.screen.set('chat');\n }\n\n protected goBack() {\n this.chatService.deselectThread();\n this.screen.set('threads');\n }\n\n protected onKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.send();\n }\n }\n\n protected send() {\n if (this.chatService.isAgentWorking()) return;\n const text = this.text().trim();\n if (!text) return;\n\n this.text.set('');\n this.chatService.send(text).subscribe();\n }\n\n protected newChat() {\n this.chatService.deselectThread();\n this.screen.set('chat');\n }\n}\n","<div class=\"w-full h-full relative overflow-hidden bg-slate-5\">\n <!-- ═══ SCREEN 1: THREADS ═══ -->\n <div\n class=\"absolute inset-0 flex flex-col transition-transform duration-300 ease-out\"\n [ngClass]=\"\n screen() === 'threads' ? 'translate-x-0' : 'ltr:-translate-x-full rtl:translate-x-full'\n \"\n >\n <!-- Threads header -->\n <div class=\"shrink-0 px-5 pt-5 pb-4 flex items-center justify-between\">\n <div>\n <h2 class=\"text-[15px] font-semibold text-slate-800 tracking-tight\">\n {{ 'translate_threads' | translate }}\n </h2>\n <p class=\"text-[11px] text-slate-400 mt-0.5\">\n {{\n 'translate_n_conversations' | translate: { count: chatService.threads()?.length ?? 0 }\n }}\n </p>\n </div>\n <button\n (click)=\"newChat()\"\n class=\"inline-flex items-center gap-1.5 text-[12px] font-medium text-slate-100 bg-slate-800 px-3 py-1.5 rounded-md hover:bg-slate-700 active:bg-slate-900 transition-colors cursor-pointer\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M8 3v10M3 8h10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ 'translate_new' | translate }}\n </button>\n </div>\n\n <!-- Threads list -->\n <div class=\"flex-1 overflow-y-auto px-3 pb-3\">\n <!-- Threads loading skeleton -->\n @if (chatService.threads() === undefined) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"flex items-center gap-3 px-3 py-3 mb-0.5\">\n <div class=\"skeleton shrink-0 size-8\"></div>\n <div class=\"flex-1 flex flex-col gap-1.5\">\n <div class=\"skeleton h-3.5\" [style.width]=\"40 + i * 12 + '%'\"></div>\n </div>\n </div>\n }\n } @else {\n @for (thread of chatService.threads(); track thread.id) {\n <button\n (click)=\"selectThread(thread)\"\n class=\"group w-full text-start px-3 py-3 rounded-lg flex items-center gap-3 transition-colors cursor-pointer mb-0.5\"\n [ngClass]=\"{\n 'bg-slate-200 text-slate-100': thread.id === chatService.selectedThread()?.id,\n 'text-slate-600 hover:bg-slate-100 active:bg-slate-150':\n thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n <!-- Thread icon -->\n <div\n class=\"shrink-0 size-8 rounded-md flex items-center justify-center text-[11px] font-semibold rtl:transform rtl:rotate-180\"\n [ngClass]=\"{\n 'bg-slate-700 text-slate-300': thread.id === chatService.selectedThread()?.id,\n 'bg-slate-200 text-slate-500': thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M2.5 4.5h11M2.5 8h7M2.5 11.5h9\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n\n <!-- Thread info -->\n <div class=\"min-w-0 flex-1\">\n <p\n class=\"text-[13px] font-medium truncate leading-tight\"\n [ngClass]=\"{\n 'text-slate-100': thread.id === chatService.selectedThread()?.id,\n 'text-slate-700': thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n {{ thread.title ?? ('translate_untitled' | translate) }}\n </p>\n </div>\n\n <!-- Delete button -->\n <button\n (click)=\"$event.stopPropagation(); chatService.deleteThread(thread.id).subscribe()\"\n class=\"shrink-0 opacity-0 group-hover:opacity-100 transition-opacity size-7 rounded-md flex items-center justify-center cursor-pointer\"\n [ngClass]=\"{\n 'hover:bg-slate-600 text-slate-400': thread.id === chatService.selectedThread()?.id,\n 'hover:bg-slate-200 text-slate-400': thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M4 4l8 8M12 4l-8 8\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n\n <!-- Arrow -->\n <svg\n class=\"shrink-0 transition-colors rtl:transform rtl:rotate-180\"\n [ngClass]=\"{\n 'text-slate-500': thread.id === chatService.selectedThread()?.id,\n 'text-slate-300 group-hover:text-slate-400':\n thread.id !== chatService.selectedThread()?.id,\n }\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n\n @if (!chatService.threads()?.length) {\n <div class=\"flex flex-col items-center justify-center py-16 text-center\">\n <div class=\"size-10 rounded-lg bg-slate-200 flex items-center justify-center mb-3\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"none\" class=\"text-slate-400\">\n <path\n d=\"M2.5 4.5h11M2.5 8h7M2.5 11.5h9\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n <p class=\"text-[13px] text-slate-400 font-medium\">No threads yet</p>\n <p class=\"text-[11px] text-slate-350 mt-1\">Start a new conversation</p>\n </div>\n }\n }\n </div>\n </div>\n\n <!-- ═══ SCREEN 2: CHAT ═══ -->\n <div\n class=\"absolute inset-0 flex flex-col transition-transform duration-300 ease-out\"\n [ngClass]=\"screen() === 'chat' ? 'translate-x-0' : 'ltr:translate-x-full rtl:-translate-x-full'\"\n >\n <!-- Chat header -->\n <div class=\"shrink-0 h-12 px-4 flex items-center gap-3 border-b border-slate-200 bg-white\">\n <!-- Back button -->\n <button\n (click)=\"goBack()\"\n class=\"shrink-0 size-8 rounded-md flex items-center justify-center text-slate-400 hover:text-slate-600 hover:bg-slate-100 transition-colors cursor-pointer\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"rtl:transform rtl:rotate-180\"\n >\n <path\n d=\"M10 3L5 8l5 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n\n <!-- Title -->\n <div class=\"min-w-0 flex-1\">\n <p class=\"text-[13px] font-medium text-slate-700 truncate\">\n {{ chatService.selectedThread()?.title ?? ('translate_new_chat' | translate) }}\n </p>\n </div>\n\n <!-- Debug toggle -->\n <button\n (click)=\"toggleDebugMode()\"\n class=\"shrink-0 text-[11px] font-medium px-2.5 py-1 rounded-md transition-colors cursor-pointer\"\n [ngClass]=\"{\n 'bg-amber-50 text-amber-600 hover:bg-amber-100': debugMode(),\n 'bg-slate-100 text-slate-400 hover:bg-slate-200': !debugMode(),\n }\"\n >\n {{ debugMode() ? ('translate_debug' | translate) : ('translate_normal' | translate) }}\n </button>\n </div>\n\n <!-- Messages loading skeleton -->\n @if (chatService.isLoadingMessages() && !chatService.isAgentWorking()) {\n <div class=\"flex-1 overflow-hidden p-4 flex flex-col gap-2\">\n <!-- User message skeleton -->\n <div class=\"w-full flex flex-col items-start\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-bl-none border border-slate-200 bg-slate-50 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-52\"></div>\n <div class=\"skeleton h-3 w-36\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"w-full flex flex-col items-end\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-br-none border border-slate-200 bg-slate-100 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-64\"></div>\n <div class=\"skeleton h-3 w-72\"></div>\n <div class=\"skeleton h-3 w-48\"></div>\n </div>\n </div>\n <!-- User message skeleton -->\n <div class=\"w-full flex flex-col items-start\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-bl-none border border-slate-200 bg-slate-50 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-44\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"w-full flex flex-col items-end\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-br-none border border-slate-200 bg-slate-100 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-56\"></div>\n <div class=\"skeleton h-3 w-60\"></div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Messages area -->\n <cortex-message-list class=\"flex-1 overflow-hidden\" [debugMode]=\"debugMode()\" />\n }\n\n <!-- Agent working indicator -->\n @if (chatService.isAgentWorking() && !chatService.hasPendingToolCalls()) {\n <div class=\"shrink-0 px-4 py-1.5 flex items-center gap-1.5\">\n <div class=\"flex items-center gap-[3px]\">\n <span class=\"cortex-working-dot block size-[5px] rounded-full bg-slate-400\"></span>\n <span class=\"cortex-working-dot block size-[5px] rounded-full bg-slate-400\"></span>\n <span class=\"cortex-working-dot block size-[5px] rounded-full bg-slate-400\"></span>\n </div>\n <span class=\"text-[11px] text-slate-400 font-medium\">{{\n 'translate_thinking' | translate\n }}</span>\n </div>\n }\n\n <!-- Chat input (hidden during pending tool calls) -->\n @if (!chatService.hasPendingToolCalls()) {\n <div class=\"shrink-0 p-3 bg-white border-t border-slate-200\">\n <div\n class=\"flex items-end gap-2 rounded-xl border border-slate-200 p-1.5 transition-colors\"\n [ngClass]=\"{\n 'bg-slate-100': chatService.isAgentWorking(),\n 'bg-slate-50 focus-within:border-slate-300 focus-within:bg-white':\n !chatService.isAgentWorking(),\n }\"\n >\n <textarea\n (keydown)=\"onKeydown($event)\"\n [(ngModel)]=\"text\"\n [placeholder]=\"\n chatService.isAgentWorking() ? '' : ('translate_type_a_message' | translate)\n \"\n [disabled]=\"chatService.isAgentWorking()\"\n rows=\"1\"\n class=\"flex-1 bg-transparent resize-none border-0 outline-none text-[13px] placeholder:text-slate-350 py-1.5 px-2 min-h-[28px] max-h-[120px] leading-snug disabled:cursor-not-allowed disabled:border-0\"\n [ngClass]=\"{\n 'text-slate-400': chatService.isAgentWorking(),\n 'text-slate-700': !chatService.isAgentWorking(),\n }\"\n ></textarea>\n @if (chatService.isAgentWorking()) {\n <!-- Stop button -->\n <button\n (click)=\"chatService.abort()\"\n class=\"stop-btn shrink-0 size-8 rounded-lg flex items-center justify-center cursor-pointer relative\"\n >\n <!-- Pulsing ring -->\n <span class=\"stop-btn-ring absolute inset-0 rounded-lg\"></span>\n <!-- Stop icon (rounded square) -->\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" class=\"relative z-10\">\n <rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" rx=\"2.5\" fill=\"currentColor\" />\n </svg>\n </button>\n } @else {\n <!-- Send button -->\n <button\n (click)=\"send()\"\n class=\"shrink-0 size-8 rounded-lg flex items-center justify-center transition-colors\"\n [ngClass]=\"{\n 'bg-slate-200 text-slate-400': !text().trim(),\n 'bg-slate-800 text-white hover:bg-slate-700 cursor-pointer': text().trim(),\n }\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"rtl:transform rtl:rotate-180\"\n >\n <path\n d=\"M3 8h10M9 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n </div>\n }\n </div>\n</div>\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'prettyJson', standalone: true })\nexport class PrettyJsonPipe implements PipeTransform {\n transform(value: unknown) {\n if (value == null) return '';\n const formatted = this.deepFormat(value);\n return JSON.stringify(formatted, null, 2).replace(/\\\\n/g, '\\n');\n }\n\n private deepFormat(value: unknown): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n return this.deepFormat(parsed);\n } catch {\n // Not valid JSON, fall through\n }\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => this.deepFormat(item));\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = this.deepFormat(val);\n }\n return result;\n }\n\n return value;\n }\n}\n","/*\n * Public API Surface of cortex-client\n */\n\n// Config\nexport type { CortexClientConfig, CortexClientTransport, CortexClientTheme } from './lib/config';\n\n// Services\nexport { CortexChatService } from './lib/services/cortex-chat.service';\nexport type { Thread } from './lib/services/cortex-chat.service';\nexport { CortexClientWebSocketService } from './lib/services/cortex-websocket.service';\n\n// WebSocket events\nexport type { WsEvent, ThreadTitleUpdatedEvent } from './lib/ws-events';\n\n// Components\nexport { CortexChatWidgetComponent } from './lib/components/chat-widget/chat-widget.component';\nexport { MessageListComponent } from './lib/components/message-list/message-list.component';\nexport { MessageComponent } from './lib/components/message/message.component';\nexport { MessagePartComponent } from './lib/components/message-part/message-part.component';\nexport { MessageTextPartComponent } from './lib/components/message-text-part/message-text-part.component';\nexport { MessageToolCallAnimatedComponent } from './lib/components/message-tool-call-animated/message-tool-call-animated.component';\nexport { MessageToolCallPartComponent } from './lib/components/message-tool-call-part/message-tool-call-part.component';\nexport { MessageReasoningPartComponent } from './lib/components/message-reasoning-part/message-reasoning-part.component';\nexport { MessageReasoningAnimatedComponent } from './lib/components/message-reasoning-animated/message-reasoning-animated.component';\nexport {\n MessageCaptureFilesPartComponent,\n FileInputComponent,\n} from './lib/components/message-capture-file-part/message-capture-files-part.component';\nexport { JsonTreeComponent } from './lib/components/json-tree/json-tree.component';\n\n// Pipes\nexport { MarkedPipe } from './lib/pipes/marked.pipe';\nexport { HighlightPipe } from './lib/pipes/highlight.pipe';\nexport { PrettyJsonPipe } from './lib/pipes/pretty-json.pipe';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.CortexChatService"],"mappings":"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"}
1
+ {"version":3,"file":"m6d-cortex-client.mjs","sources":["../../../projects/cortex-client/src/lib/config.ts","../../../projects/cortex-client/src/lib/services/cortex-websocket.service.ts","../../../projects/cortex-client/src/lib/services/cortex-chat.service.ts","../../../projects/cortex-client/src/lib/pipes/marked.pipe.ts","../../../projects/cortex-client/src/lib/components/message-text-part/message-text-part.component.ts","../../../projects/cortex-client/src/lib/components/message-text-part/message-text-part.component.html","../../../projects/cortex-client/src/lib/components/message-reasoning-part/message-reasoning-part.component.ts","../../../projects/cortex-client/src/lib/components/message-reasoning-part/message-reasoning-part.component.html","../../../projects/cortex-client/src/lib/pipes/highlight.pipe.ts","../../../projects/cortex-client/src/lib/components/json-tree/json-tree.component.ts","../../../projects/cortex-client/src/lib/components/json-tree/json-tree.component.html","../../../projects/cortex-client/src/lib/components/message-tool-call-part/message-tool-call-part.component.ts","../../../projects/cortex-client/src/lib/components/message-tool-call-part/message-tool-call-part.component.html","../../../projects/cortex-client/src/lib/components/message-capture-file-part/message-capture-files-part.component.ts","../../../projects/cortex-client/src/lib/components/message-capture-file-part/message-capture-files-part.component.html","../../../projects/cortex-client/src/lib/components/message-tool-call-animated/message-tool-call-animated.component.ts","../../../projects/cortex-client/src/lib/components/message-tool-call-animated/message-tool-call-animated.component.html","../../../projects/cortex-client/src/lib/components/message-reasoning-animated/message-reasoning-animated.component.ts","../../../projects/cortex-client/src/lib/components/message-reasoning-animated/message-reasoning-animated.component.html","../../../projects/cortex-client/src/lib/components/message-part/message-part.component.ts","../../../projects/cortex-client/src/lib/components/message-part/message-part.component.html","../../../projects/cortex-client/src/lib/components/message/message.component.ts","../../../projects/cortex-client/src/lib/components/message/message.component.html","../../../projects/cortex-client/src/lib/components/message-list/message-list.component.ts","../../../projects/cortex-client/src/lib/components/message-list/message-list.component.html","../../../projects/cortex-client/src/lib/i18n/translate-loader.ts","../../../projects/cortex-client/src/lib/components/chat-widget/chat-widget.component.ts","../../../projects/cortex-client/src/lib/components/chat-widget/chat-widget.component.html","../../../projects/cortex-client/src/lib/pipes/pretty-json.pipe.ts","../../../projects/cortex-client/src/public-api.ts","../../../projects/cortex-client/src/m6d-cortex-client.ts"],"sourcesContent":["import { Signal, Type, InjectionToken } from '@angular/core';\n\nexport type CortexClientTransport = {\n baseUrl: string | Signal<string>;\n getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;\n};\n\nexport type CortexClientConfig = {\n locale: string;\n theme?: CortexClientTheme;\n transport: CortexClientTransport;\n wsUrl?: string;\n toolComponents?: Record<string, Type<unknown>>;\n onToolCall?: (toolCall: {\n toolName: string;\n toolCallId: string;\n args: Record<string, unknown>;\n dynamic: boolean;\n }) => Promise<unknown> | unknown;\n};\n\nexport type CortexClientTheme = {\n primaryColor?: string;\n backgroundColor?: string;\n surfaceColor?: string;\n textColor?: string;\n borderRadius?: string;\n customProperties?: Record<string, string>;\n};\n\nexport const CORTEX_CLIENT_CONFIG = new InjectionToken<CortexClientConfig>('CORTEX_CLIENT_CONFIG');\n","import { inject, Injectable, NgZone, Signal } from '@angular/core';\nimport { Observable, retry, share, timer } from 'rxjs';\nimport { CORTEX_CLIENT_CONFIG } from '../config';\nimport { WsEvent } from '../ws-events';\n\n@Injectable()\nexport class CortexClientWebSocketService {\n private readonly events$: Observable<WsEvent>;\n\n constructor() {\n const config = inject(CORTEX_CLIENT_CONFIG);\n const ngZone = inject(NgZone);\n\n this.events$ = new Observable<WsEvent>((subscriber) => {\n const wsUrl = config.wsUrl ?? deriveWsUrl(config.transport.baseUrl);\n let ws: WebSocket | undefined;\n\n Promise.resolve(config.transport.getAuthHeaders()).then((headers) => {\n if (subscriber.closed) return;\n\n const fullWsUrl = appendTokenToUrl(wsUrl, headers);\n ws = new WebSocket(fullWsUrl);\n\n ws.addEventListener('message', (event) => {\n let parsed: WsEvent;\n try {\n parsed = JSON.parse(event.data);\n } catch {\n return;\n }\n ngZone.run(() => subscriber.next(parsed));\n });\n\n ws.addEventListener('error', (e) => subscriber.error(e));\n ws.addEventListener('close', () => subscriber.error(new Error('WebSocket closed')));\n });\n\n return () => ws?.close();\n }).pipe(\n retry({\n delay: (_: unknown, retryCount: number) =>\n timer(Math.min(1000 * 2 ** (retryCount - 1), 30_000)),\n }),\n share(),\n );\n }\n\n get events() {\n return this.events$;\n }\n}\n\nfunction deriveWsUrl(baseUrl: string | Signal<string>) {\n const url = typeof baseUrl === 'string' ? baseUrl : baseUrl();\n const parsed = new URL(url, window.location.origin);\n parsed.protocol = parsed.protocol === 'https:' ? 'wss:' : 'ws:';\n parsed.pathname = parsed.pathname.replace(/\\/$/, '') + '/ws';\n return parsed.toString();\n}\n\nfunction appendTokenToUrl(wsUrl: string, headers: Record<string, string>) {\n const authHeader = headers['Authorization'] ?? headers['authorization'];\n if (!authHeader?.startsWith('Bearer ')) return wsUrl;\n\n const token = authHeader.slice(7);\n const separator = wsUrl.includes('?') ? '&' : '?';\n return `${wsUrl}${separator}token=${encodeURIComponent(token)}`;\n}\n","import { DestroyRef, inject, Injectable, Signal, signal } from '@angular/core';\nimport { Chat } from '@ai-sdk/angular';\nimport { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls, UIMessage } from 'ai';\nimport { concatMap, defer, finalize, map, of, pipe, Subject, switchMap, tap } from 'rxjs';\nimport { fromPromise } from 'rxjs/internal/observable/innerFrom';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CORTEX_CLIENT_CONFIG, CortexClientConfig } from '../config';\nimport { CortexClientWebSocketService } from './cortex-websocket.service';\n\nexport type Thread = {\n id: string;\n title?: string;\n createdAt?: string;\n updatedAt?: string;\n};\n\n@Injectable()\nexport class CortexChatService {\n readonly threads = signal<Thread[] | undefined>(undefined);\n readonly selectedThread = signal<Thread | undefined>(undefined);\n readonly chat = signal<Chat | undefined>(undefined);\n readonly isLoadingMessages = signal(false);\n readonly isAgentWorking = signal(false);\n readonly hasPendingToolCalls = signal(false);\n\n private events = new Subject<'onThreadSelected' | 'onSend' | 'onData' | 'onError' | 'onFinish'>();\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n private readonly wsService = inject(CortexClientWebSocketService);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n this.reloadThreads().subscribe();\n this.subscribeToWsEvents();\n }\n\n get events$() {\n return this.events.asObservable();\n }\n\n selectThread(thread: Thread, options?: { skipLoadingMessages?: boolean }) {\n if (this.isLoadingMessages()) return of();\n if (this.selectedThread()?.id === thread.id) return of();\n\n return (\n options?.skipLoadingMessages\n ? of([])\n : defer(() => {\n this.isLoadingMessages.set(true);\n return fromPromise(this.fetchJson<UIMessage[]>(`/threads/${thread.id}/messages`)).pipe(\n finalize(() => this.isLoadingMessages.set(false)),\n );\n })\n ).pipe(\n tap((messages) => {\n const chat = new Chat({\n id: thread.id,\n sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,\n\n onData: () => {\n this.events.next('onData');\n },\n\n onToolCall: async ({ toolCall }) => {\n if (!this.config.onToolCall) return;\n\n const tc = toolCall as unknown as {\n toolName: string;\n toolCallId: string;\n args: Record<string, unknown>;\n dynamic: boolean;\n };\n const result = this.config.onToolCall(tc);\n if (result == null) return;\n\n const output = result instanceof Promise ? await result : result;\n chat.addToolOutput({\n tool: tc.toolName,\n toolCallId: tc.toolCallId,\n output,\n });\n },\n\n onError: () => {\n this.isAgentWorking.set(false);\n this.hasPendingToolCalls.set(false);\n this.events.next('onError');\n },\n\n onFinish: () => {\n const lastAssistantMsg = [...chat.messages]\n .reverse()\n .find((m) => m.role === 'assistant');\n const pending = lastAssistantMsg?.parts?.some(\n (p) =>\n p.type.startsWith('tool-') &&\n (p as { state?: string }).state !== 'output-available' &&\n (p as { state?: string }).state !== 'output-error' &&\n (p as { state?: string }).state !== 'output-denied',\n );\n\n if (pending) {\n this.hasPendingToolCalls.set(true);\n } else {\n this.isAgentWorking.set(false);\n this.hasPendingToolCalls.set(false);\n }\n this.events.next('onFinish');\n },\n\n messages: messages as UIMessage[],\n transport: new DefaultChatTransport({\n api: this.resolveUrl('/chat'),\n headers: async () => await this.resolveHeaders(),\n prepareSendMessagesRequest: ({ messages, id, body, ...rest }) => {\n this.isAgentWorking.set(true);\n this.hasPendingToolCalls.set(false);\n return {\n ...rest,\n body: {\n ...body,\n id,\n messages: [messages.at(-1)],\n },\n };\n },\n }),\n });\n\n fixChat(chat);\n this.chat.set(chat);\n this.selectedThread.set(thread);\n\n // Check if loaded messages have pending tool calls\n const lastAssistantMsg = [...messages].reverse().find((m) => m.role === 'assistant');\n const pending = lastAssistantMsg?.parts?.some(\n (p) =>\n p.type.startsWith('tool-') &&\n (p as { state?: string }).state !== 'output-available' &&\n (p as { state?: string }).state !== 'output-error' &&\n (p as { state?: string }).state !== 'output-denied',\n );\n if (pending) {\n this.hasPendingToolCalls.set(true);\n }\n\n this.events.next('onThreadSelected');\n }),\n );\n }\n\n deselectThread() {\n if (!this.selectedThread()) return;\n\n this.abort();\n this.selectedThread.set(undefined);\n this.chat.set(undefined);\n }\n\n send(prompt: string) {\n if (this.isAgentWorking()) return of();\n\n const ensureThread = this.selectedThread()\n ? of(undefined)\n : fromPromise(\n this.fetchJson<Thread>('/threads', {\n method: 'POST',\n body: JSON.stringify({ prompt }),\n }),\n ).pipe(\n switchMap((thread) =>\n this.selectThread(thread, { skipLoadingMessages: true }).pipe(map(() => undefined)),\n ),\n tap(() => this.reloadThreads().subscribe()),\n );\n\n return ensureThread.pipe(\n switchMap(() => fromPromise(this.chat()!.sendMessage({ text: prompt }))),\n tap(() => this.events.next('onSend')),\n );\n }\n\n abort() {\n const chat = this.chat();\n if (!chat || !this.isAgentWorking()) return;\n\n chat.stop();\n this.isAgentWorking.set(false);\n this.hasPendingToolCalls.set(false);\n\n const threadId = this.selectedThread()?.id;\n if (!threadId) return;\n this.reloadMessages(threadId).subscribe((messages) => {\n if (!this.chat()) return;\n this.chat()!.messages = messages;\n });\n }\n\n deleteThread(threadId: string) {\n if (this.selectedThread()?.id === threadId) this.deselectThread();\n\n return fromPromise(this.fetchJson(`/threads/${threadId}`, { method: 'DELETE' })).pipe(\n concatMap(() => this.reloadThreads()),\n );\n }\n\n private subscribeToWsEvents() {\n this.wsService.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {\n switch (event.type) {\n case 'thread:title-updated':\n this.onThreadTitleUpdated(event.payload);\n break;\n }\n });\n }\n\n private onThreadTitleUpdated(payload: { threadId: string; title: string }) {\n const current = this.threads();\n if (current) {\n this.threads.set(\n current.map((t) => (t.id === payload.threadId ? { ...t, title: payload.title } : t)),\n );\n }\n\n const selected = this.selectedThread();\n if (selected?.id === payload.threadId) {\n this.selectedThread.set({ ...selected, title: payload.title });\n }\n }\n\n private reloadThreads() {\n return fromPromise(this.fetchJson<Thread[]>('/threads')).pipe(\n tap((threads) => this.threads.set(threads)),\n );\n }\n\n private reloadMessages(threadId: string) {\n return fromPromise(this.fetchJson<UIMessage[]>(`/threads/${threadId}/messages`));\n }\n\n private resolveUrl(path: string) {\n const baseUrl = this.config.transport.baseUrl;\n const base = typeof baseUrl === 'string' ? baseUrl : (baseUrl as Signal<string>)();\n return base.replace(/\\/$/, '') + path;\n }\n\n private async resolveHeaders() {\n return await Promise.resolve(this.config.transport.getAuthHeaders());\n }\n\n private async fetchJson<T>(path: string, init?: RequestInit) {\n const url = this.resolveUrl(path);\n const headers = await this.resolveHeaders();\n const res = await fetch(url, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n ...init?.headers,\n },\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n const text = await res.text();\n return text ? (JSON.parse(text) as T) : (undefined as T);\n }\n}\n\n/**\n * Override snapshot to avoid structuredClone failing on\n * Object.defineProperty getter/setter parts.\n */\nfunction fixChat(chat: Chat) {\n function deepClone<T>(value: T): T {\n if (value === null || value === undefined) return value;\n if (typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(deepClone) as unknown as T;\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value as Record<string, unknown>)) {\n result[key] = deepClone((value as Record<string, unknown>)[key]);\n }\n return result as T;\n }\n\n (chat as unknown as { state: { snapshot: unknown } }).state.snapshot = deepClone;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { marked } from 'marked';\nimport DOMPurify from 'dompurify';\n\n@Pipe({\n name: 'marked',\n standalone: true,\n})\nexport class MarkedPipe implements PipeTransform {\n constructor(private readonly sanitizer: DomSanitizer) {}\n\n transform(value: string | undefined | null): SafeHtml {\n if (!value) {\n return '';\n }\n\n let html = marked.parse(value, { async: false }) as string;\n\n html = html\n .replace(/<table>/g, '<div style=\"overflow-x:auto\"><table style=\"width:auto\">')\n .replace(/<\\/table>/g, '</table></div>')\n .replace(/<(t[hd])([\\s>])/g, '<$1 style=\"padding:0.5rem 1rem\"$2');\n\n return this.sanitizer.bypassSecurityTrustHtml(DOMPurify.sanitize(html));\n }\n}\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { TextUIPart, UIMessage } from 'ai';\nimport { MarkedPipe } from '../../pipes/marked.pipe';\n\n@Component({\n selector: 'cortex-message-text-part',\n templateUrl: './message-text-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgClass, MarkedPipe],\n})\nexport class MessageTextPartComponent {\n public readonly role = input.required<UIMessage['role']>();\n public readonly textPart = input.required<TextUIPart>();\n}\n","<div\n class=\"w-full flex flex-col\"\n [ngClass]=\"{\n 'items-end': role() === 'assistant',\n 'items-start': role() === 'user',\n }\"\n>\n <div\n class=\"max-w-4/5 text-[13px] leading-relaxed p-4 rounded-2xl border border-slate-200 prose\"\n [ngClass]=\"{\n 'bg-slate-100 text-slate-700 ltr:rounded-br-none rtl:rounded-bl-none': role() === 'assistant',\n 'bg-slate-50 text-slate-700 ltr:rounded-bl-none rtl:rounded-br-none': role() === 'user',\n }\"\n [innerHTML]=\"textPart().text | marked\"\n ></div>\n</div>\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { ReasoningUIPart } from 'ai';\n\n@Component({\n selector: 'cortex-message-reasoning-part',\n templateUrl: './message-reasoning-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MessageReasoningPartComponent {\n public readonly reasoningPart = input.required<ReasoningUIPart>();\n}\n","@let p = reasoningPart();\n<details class=\"group w-full rounded-lg border border-slate-200 bg-slate-50 overflow-hidden\">\n <summary\n class=\"list-none [&::-webkit-details-marker]:hidden cursor-pointer select-none px-4 py-3 flex items-center gap-3\"\n >\n <div class=\"flex items-center gap-2 min-w-0 flex-1\">\n <span\n class=\"inline-flex h-6 w-6 items-center justify-center rounded bg-indigo-100 text-indigo-600\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M10 2C6.686 2 4 4.686 4 8c0 1.655.672 3.154 1.757 4.243.362.363.576.858.576 1.371V14.5a1 1 0 0 0 1 1h5.334a1 1 0 0 0 1-1v-.886c0-.513.214-1.008.576-1.371A5.978 5.978 0 0 0 16 8c0-3.314-2.686-6-6-6Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M7.5 17.5h5M8.5 8a2 2 0 0 1 2-2\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <div class=\"font-medium text-slate-700 text-sm\">Reasoning</div>\n @if (p.state) {\n <span\n class=\"inline-flex items-center rounded px-1.5 py-0.5 text-[11px] font-medium\"\n [class.bg-amber-100.text-amber-700]=\"p.state === 'streaming'\"\n [class.bg-emerald-100.text-emerald-700]=\"p.state === 'done'\"\n >\n {{ p.state === 'streaming' ? 'Streaming' : 'Done' }}\n </span>\n }\n </div>\n </div>\n </div>\n\n <span\n class=\"ml-auto inline-flex h-6 w-6 items-center justify-center rounded text-slate-400 transition group-open:rotate-180\"\n aria-hidden=\"true\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"m5.75 8.25 4.25 4.25 4.25-4.25\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </summary>\n\n <div class=\"px-4 pb-4\">\n <div class=\"mt-1 rounded bg-white border border-slate-200 p-3\">\n <pre\n class=\"m-0 whitespace-pre-wrap wrap-break-word font-mono text-xs leading-relaxed text-slate-700\"\n >{{ p.text.trim() ? p.text : 'No reasoning provided.' }}</pre\n >\n </div>\n </div>\n</details>\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport hljs from 'highlight.js/lib/core';\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport json from 'highlight.js/lib/languages/json';\nimport sql from 'highlight.js/lib/languages/sql';\n\nhljs.registerLanguage('javascript', javascript);\nhljs.registerLanguage('json', json);\nhljs.registerLanguage('cypher', sql);\n\n@Pipe({ name: 'highlight', standalone: true })\nexport class HighlightPipe implements PipeTransform {\n constructor(private readonly sanitizer: DomSanitizer) {}\n\n transform(code: string, lang: string): SafeHtml {\n if (!code) return '';\n\n const highlighted = hljs.getLanguage(lang)\n ? hljs.highlight(code, { language: lang }).value\n : this.escapeHtml(code);\n\n return this.sanitizer.bypassSecurityTrustHtml(highlighted);\n }\n\n private escapeHtml(str: string) {\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\n@Component({\n selector: 'cortex-json-tree',\n templateUrl: './json-tree.component.html',\n styleUrl: './json-tree.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet],\n host: { class: 'block font-mono text-[12px] leading-5 select-text' },\n})\nexport class JsonTreeComponent {\n public readonly data = input.required<unknown>();\n public readonly expandDepth = input<number>(1);\n\n private collapsedPaths = new Set<string>();\n private userToggled = new Set<string>();\n\n protected isCollapsed(path: string, depth: number) {\n if (this.userToggled.has(path)) {\n return this.collapsedPaths.has(path);\n }\n return depth >= this.expandDepth();\n }\n\n protected toggle(path: string, depth: number) {\n this.userToggled.add(path);\n const currentlyCollapsed = this.isCollapsed(path, depth);\n if (currentlyCollapsed) {\n this.collapsedPaths.delete(path);\n } else {\n this.collapsedPaths.add(path);\n }\n }\n\n protected isObject(value: unknown) {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n }\n\n protected isArray(value: unknown) {\n return Array.isArray(value);\n }\n\n protected objectEntries(value: unknown) {\n if (!this.isObject(value)) return [];\n return Object.entries(value as Record<string, unknown>);\n }\n\n protected arrayItems(value: unknown) {\n return Array.isArray(value) ? value : [];\n }\n\n protected objectLength(value: unknown) {\n if (!this.isObject(value)) return 0;\n return Object.keys(value as Record<string, unknown>).length;\n }\n\n protected arrayLength(value: unknown) {\n return Array.isArray(value) ? value.length : 0;\n }\n\n protected formatPrimitive(value: unknown) {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') return JSON.stringify(value);\n return String(value);\n }\n\n protected primitiveClass(value: unknown) {\n if (value === null || value === undefined) return 'jt-null';\n if (typeof value === 'string') return 'jt-string';\n if (typeof value === 'number') return 'jt-number';\n if (typeof value === 'boolean') return 'jt-boolean';\n return '';\n }\n\n protected isContainer(value: unknown) {\n return this.isObject(value) || this.isArray(value);\n }\n\n protected parsed(value: unknown) {\n return this.deepParse(value);\n }\n\n private deepParse(value: unknown): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n return this.deepParse(JSON.parse(trimmed));\n } catch {\n return value;\n }\n }\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.deepParse(item));\n }\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = this.deepParse(val);\n }\n return result;\n }\n return value;\n }\n}\n","<!-- Entry point: parse and render the root value -->\n<ng-container\n *ngTemplateOutlet=\"valueTemplate; context: { $implicit: parsed(data()), path: '$', depth: 0 }\"\n/>\n\n<!-- Recursive value renderer -->\n<ng-template #valueTemplate let-value let-path=\"path\" let-depth=\"depth\">\n @if (isObject(value)) {\n @if (objectLength(value) === 0) {\n <span class=\"jt-bracket\">{{ '{' }}{{ '}' }}</span>\n } @else {\n <span class=\"jt-toggle\" (click)=\"toggle(path, depth); $event.stopPropagation()\" role=\"button\">\n <span class=\"jt-arrow\" [class.jt-arrow--collapsed]=\"isCollapsed(path, depth)\">&#9662;</span>\n <span class=\"jt-bracket\">{{ '{' }}</span>\n </span>\n @if (isCollapsed(path, depth)) {\n <span\n class=\"jt-collapsed-hint\"\n (click)=\"toggle(path, depth); $event.stopPropagation()\"\n role=\"button\"\n >{{ objectLength(value) }}\n {{ objectLength(value) === 1 ? 'property' : 'properties' }}</span\n ><span class=\"jt-bracket\">{{ '}' }}</span>\n } @else {\n <div class=\"jt-indent\">\n @for (entry of objectEntries(value); track entry[0]; let last = $last) {\n <div class=\"jt-line\">\n <span class=\"jt-key\">\"{{ entry[0] }}\"</span><span class=\"jt-colon\">: </span>\n @if (isContainer(entry[1])) {\n <ng-container\n *ngTemplateOutlet=\"\n valueTemplate;\n context: { $implicit: entry[1], path: path + '.' + entry[0], depth: depth + 1 }\n \"\n />\n } @else {\n <span [class]=\"primitiveClass(entry[1])\">{{ formatPrimitive(entry[1]) }}</span>\n }\n @if (!last) {\n <span class=\"jt-comma\">,</span>\n }\n </div>\n }\n </div>\n <span class=\"jt-bracket\">{{ '}' }}</span>\n }\n }\n } @else if (isArray(value)) {\n @if (arrayLength(value) === 0) {\n <span class=\"jt-bracket\">[]</span>\n } @else {\n <span class=\"jt-toggle\" (click)=\"toggle(path, depth); $event.stopPropagation()\" role=\"button\">\n <span class=\"jt-arrow\" [class.jt-arrow--collapsed]=\"isCollapsed(path, depth)\">&#9662;</span>\n <span class=\"jt-bracket\">[</span>\n </span>\n @if (isCollapsed(path, depth)) {\n <span\n class=\"jt-collapsed-hint\"\n (click)=\"toggle(path, depth); $event.stopPropagation()\"\n role=\"button\"\n >{{ arrayLength(value) }} {{ arrayLength(value) === 1 ? 'item' : 'items' }}</span\n ><span class=\"jt-bracket\">]</span>\n } @else {\n <div class=\"jt-indent\">\n @for (item of arrayItems(value); track $index; let last = $last) {\n <div class=\"jt-line\">\n @if (isContainer(item)) {\n <ng-container\n *ngTemplateOutlet=\"\n valueTemplate;\n context: { $implicit: item, path: path + '[' + $index + ']', depth: depth + 1 }\n \"\n />\n } @else {\n <span [class]=\"primitiveClass(item)\">{{ formatPrimitive(item) }}</span>\n }\n @if (!last) {\n <span class=\"jt-comma\">,</span>\n }\n </div>\n }\n </div>\n <span class=\"jt-bracket\">]</span>\n }\n }\n } @else {\n <span [class]=\"primitiveClass(value)\">{{ formatPrimitive(value) }}</span>\n }\n</ng-template>\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ToolUIPart } from 'ai';\nimport { HighlightPipe } from '../../pipes/highlight.pipe';\nimport { JsonTreeComponent } from '../json-tree/json-tree.component';\n\n@Component({\n selector: 'cortex-message-tool-call-part',\n templateUrl: './message-tool-call-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [HighlightPipe, NgClass, TranslatePipe, JsonTreeComponent],\n})\nexport class MessageToolCallPartComponent {\n private static readonly CODE_FIELDS: Record<string, string> = {\n code: 'javascript',\n query: 'cypher',\n };\n\n public readonly toolCallPart = input.required<ToolUIPart>();\n\n protected readonly codeSnippets = computed(() => {\n const inp = this.toolCallPart().input;\n if (!inp || typeof inp !== 'object') return [];\n\n const record = inp as Record<string, unknown>;\n const snippets: { key: string; lang: string; value: string }[] = [];\n\n for (const [key, lang] of Object.entries(MessageToolCallPartComponent.CODE_FIELDS)) {\n if (key in record && typeof record[key] === 'string') {\n snippets.push({\n key,\n lang,\n value: (record[key] as string).replace(/\\\\n/g, '\\n'),\n });\n }\n }\n return snippets;\n });\n\n protected readonly remainingInput = computed(() => {\n const inp = this.toolCallPart().input;\n if (!inp || typeof inp !== 'object') return inp;\n\n const record = inp as Record<string, unknown>;\n const codeKeys = Object.keys(MessageToolCallPartComponent.CODE_FIELDS);\n const remaining: Record<string, unknown> = {};\n let hasKeys = false;\n\n for (const [key, val] of Object.entries(record)) {\n if (!codeKeys.includes(key)) {\n remaining[key] = val;\n hasKeys = true;\n }\n }\n return hasKeys ? remaining : null;\n });\n\n protected toolName() {\n const type = this.toolCallPart().type;\n if (!type) return '';\n return type.startsWith('tool-') ? type.slice('tool-'.length) : type;\n }\n}\n","<details class=\"group w-full rounded-lg border border-slate-200 bg-slate-50 overflow-hidden\">\n <summary\n class=\"list-none [&::-webkit-details-marker]:hidden cursor-pointer select-none px-4 py-3 group-open:border-b group-open:border-slate-200\"\n >\n <div class=\"flex items-start gap-3\">\n <div\n class=\"shrink-0 mt-0.5 size-7 rounded bg-slate-800 text-white flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-4\" fill=\"none\">\n <path\n d=\"M6.5 6.5 3.75 10l2.75 3.5M13.5 6.5 16.25 10l-2.75 3.5M11.25 5.75 8.75 14.25\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex items-center gap-2\">\n <div class=\"min-w-0 flex-1\">\n <div class=\"flex items-center gap-2 min-w-0\">\n <div\n class=\"font-medium text-slate-800 text-sm truncate\"\n [attr.title]=\"toolCallPart().title || null\"\n >\n {{ toolCallPart().title ?? 'Tool call' }}\n </div>\n @if (toolName()) {\n <span\n class=\"hidden sm:inline-flex items-center rounded bg-slate-200 px-1.5 py-0.5 text-[11px] font-medium text-slate-600 font-mono\"\n [attr.title]=\"toolCallPart().type || null\"\n >{{ toolName() }}</span\n >\n }\n </div>\n <div class=\"mt-0.5 text-[11px] text-slate-500 break-all\">\n <span class=\"font-medium text-slate-600\">ID</span>\n <span class=\"font-mono\"> {{ toolCallPart().toolCallId }}</span>\n @if (toolCallPart().providerExecuted) {\n <span class=\"ml-2 inline-flex items-center gap-1 text-emerald-700\">\n <span class=\"size-1.5 rounded-full bg-emerald-500\"></span>\n provider\n </span>\n }\n </div>\n </div>\n\n <div class=\"flex items-center gap-2\">\n <span\n class=\"inline-flex items-center gap-1.5 rounded px-2 py-1 text-[11px] font-medium border\"\n [ngClass]=\"{\n 'bg-emerald-50 text-emerald-700 border-emerald-200':\n toolCallPart().state === 'output-available',\n 'bg-red-50 text-red-700 border-red-200': toolCallPart().state === 'output-error',\n 'bg-slate-100 text-slate-600 border-slate-200':\n toolCallPart().state === 'output-denied',\n 'bg-violet-50 text-violet-700 border-violet-200':\n toolCallPart().state === 'approval-requested' ||\n toolCallPart().state === 'approval-responded',\n 'bg-amber-50 text-amber-700 border-amber-200':\n toolCallPart().state === 'input-streaming' ||\n toolCallPart().state === 'input-available',\n }\"\n >\n @switch (toolCallPart().state) {\n @case ('input-streaming') {\n <span class=\"size-1.5 rounded-full bg-amber-500 animate-pulse\"></span>\n Calling\n }\n @case ('input-available') {\n <span class=\"size-1.5 rounded-full bg-amber-500\"></span> Input ready\n }\n @case ('approval-requested') {\n <span class=\"size-1.5 rounded-full bg-violet-500 animate-pulse\"></span>\n Needs approval\n }\n @case ('approval-responded') {\n @if (toolCallPart().approval?.approved) {\n <span class=\"size-1.5 rounded-full bg-emerald-500\"></span> Approved\n } @else {\n <span class=\"size-1.5 rounded-full bg-slate-500\"></span> Responded\n }\n }\n @case ('output-available') {\n <span class=\"size-1.5 rounded-full bg-emerald-500\"></span>\n {{ 'translate_completed' | translate }}\n }\n @case ('output-error') {\n <span class=\"size-1.5 rounded-full bg-red-500\"></span> Error\n }\n @case ('output-denied') {\n <span class=\"size-1.5 rounded-full bg-slate-500\"></span> Denied\n }\n }\n </span>\n\n <span\n class=\"inline-flex size-6 items-center justify-center rounded text-slate-400 transition group-open:rotate-180\"\n aria-hidden=\"true\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 20 20\" fill=\"none\">\n <path\n d=\"m5.75 8.25 4.25 4.25 4.25-4.25\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </span>\n </div>\n </div>\n </div>\n </div>\n </summary>\n\n <div class=\"bg-white px-4 pb-4 pt-3\">\n <div class=\"grid gap-3\">\n @for (snippet of codeSnippets(); track snippet.key) {\n <div class=\"rounded-lg border border-slate-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-slate-200 bg-slate-50\"\n >\n <div class=\"text-[11px] font-medium text-slate-600\">\n {{ snippet.key }}\n </div>\n <div class=\"text-[11px] text-slate-400 font-mono\">\n {{ snippet.lang }}\n </div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"m-0 max-h-80 overflow-auto p-3 text-[12px] leading-5 font-mono whitespace-pre wrap-break-word\"\n ><code class=\"hljs\" [innerHTML]=\"snippet.value | highlight : snippet.lang\"></code></pre>\n </div>\n }\n\n @if (remainingInput(); as remaining) {\n <div class=\"rounded-lg border border-slate-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-slate-200 bg-slate-50\"\n >\n <div class=\"text-[11px] font-medium text-slate-600\">Input</div>\n <div class=\"text-[11px] text-slate-400 font-mono\">json</div>\n </div>\n <div dir=\"ltr\" class=\"max-h-64 overflow-auto p-3\">\n <cortex-json-tree [data]=\"remaining\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-available') {\n <div class=\"rounded-lg border border-emerald-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-emerald-200 bg-emerald-50\"\n >\n <div class=\"text-[11px] font-medium text-emerald-700\">Output</div>\n <div class=\"text-[11px] text-emerald-600 font-mono\">json</div>\n </div>\n <div dir=\"ltr\" class=\"max-h-64 overflow-auto p-3\">\n <cortex-json-tree [data]=\"toolCallPart().output\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-error') {\n <div class=\"rounded-lg border border-red-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-red-200 bg-red-50\"\n >\n <div class=\"text-[11px] font-medium text-red-700\">Error</div>\n <div class=\"text-[11px] text-red-600 font-mono\">text</div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"m-0 max-h-64 overflow-auto p-3 text-[12px] leading-5 font-mono text-red-800 whitespace-pre-wrap wrap-break-word\"\n >{{ toolCallPart().errorText }}</pre\n >\n </div>\n }\n\n @if (toolCallPart().state === 'output-denied') {\n <div class=\"rounded-lg border border-slate-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-slate-200 bg-slate-50\"\n >\n <div class=\"text-[11px] font-medium text-slate-600\">Denied</div>\n <div class=\"text-[11px] text-slate-500 font-mono\">approval</div>\n </div>\n <div class=\"p-3 text-[12px] text-slate-700\">\n Tool execution was denied.\n @if (toolCallPart().approval?.reason) {\n <div class=\"mt-2 rounded bg-slate-50 border border-slate-200 p-2\">\n <div class=\"text-[11px] font-medium text-slate-600\">Reason</div>\n <div class=\"mt-1 font-mono text-[12px] text-slate-700 wrap-break-word\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-requested') {\n <div class=\"rounded-lg border border-violet-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-violet-200 bg-violet-50\"\n >\n <div class=\"text-[11px] font-medium text-violet-700\">Approval requested</div>\n <div class=\"text-[11px] text-violet-600 font-mono\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"p-3 text-[12px] text-violet-800\">\n Waiting for approval to execute this tool.\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-responded') {\n <div class=\"rounded-lg border border-violet-200 overflow-hidden\">\n <div\n class=\"px-3 py-2 flex items-center justify-between border-b border-violet-200 bg-violet-50\"\n >\n <div class=\"text-[11px] font-medium text-violet-700\">Approval response</div>\n <div class=\"text-[11px] text-violet-600 font-mono\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"p-3 text-[12px] text-violet-800\">\n @if (toolCallPart().approval?.approved) {\n Approved.\n } @else {\n Response received.\n }\n @if (toolCallPart().approval?.reason) {\n <div class=\"mt-2 rounded bg-violet-50 border border-violet-200 p-2\">\n <div class=\"text-[11px] font-medium text-violet-700\">Reason</div>\n <div class=\"mt-1 font-mono text-[12px] text-violet-800 wrap-break-word\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</details>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n signal,\n forwardRef,\n Signal,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n FormBuilder,\n FormControl,\n NG_VALUE_ACCESSOR,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { ToolUIPart, UIMessage } from 'ai';\nimport { finalize } from 'rxjs';\nimport { fromPromise } from 'rxjs/internal/observable/innerFrom';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { CortexChatService } from '../../services/cortex-chat.service';\nimport { CORTEX_CLIENT_CONFIG } from '../../config';\n\ntype InputFile = {\n name: string;\n bytes: string;\n};\n\n@Component({\n selector: 'cortex-message-capture-files-part',\n templateUrl: './message-capture-files-part.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [ReactiveFormsModule, forwardRef(() => FileInputComponent), TranslatePipe],\n styles: [\n `\n :host {\n @apply w-full block;\n }\n `,\n ],\n})\nexport class MessageCaptureFilesPartComponent {\n public readonly message = input.required<UIMessage>();\n public readonly toolPart = input.required<ToolUIPart>();\n public readonly data = computed(\n () =>\n this.toolPart().input as {\n files: {\n label: string;\n id: string;\n }[];\n },\n );\n\n protected readonly isLoading = signal(false);\n\n protected readonly outputData = computed(() => {\n const raw = this.toolPart().output;\n if (!raw) return null;\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n return parsed as {\n status: 'success' | 'canceled';\n message?: string;\n result?: { id: string; uploadId: string }[];\n };\n });\n\n protected readonly form = computed(() => {\n const form = this.fb.group({\n files: this.fb.array(\n this.data().files.map((x) =>\n this.fb.group({\n id: new FormControl(x.id, { nonNullable: true, validators: [Validators.required] }),\n file: new FormControl(null as unknown as InputFile, {\n nonNullable: true,\n validators: [Validators.required],\n }),\n }),\n ),\n ),\n });\n\n if (this.toolPart().output) {\n form.disable();\n }\n\n return form;\n });\n\n private readonly fb = inject(FormBuilder);\n private readonly chatService = inject(CortexChatService);\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n\n protected async submit() {\n if (this.form().invalid || this.isLoading()) return;\n\n this.isLoading.set(true);\n const { files } = this.form().getRawValue();\n\n const baseUrl = this.config.transport.baseUrl;\n const base = typeof baseUrl === 'string' ? baseUrl : (baseUrl as Signal<string>)();\n const url = base.replace(/\\/$/, '') + '/files';\n\n fromPromise(\n (async () => {\n const headers = await Promise.resolve(this.config.transport.getAuthHeaders());\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({\n files,\n toolCallId: this.toolPart().toolCallId,\n message: this.message(),\n }),\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n return res.json();\n })(),\n )\n .pipe(finalize(() => this.isLoading.set(false)))\n .subscribe((result) => {\n this.chatService.chat()?.addToolOutput({\n tool: 'captureFiles',\n toolCallId: this.toolPart().toolCallId,\n output: {\n status: 'success',\n result,\n },\n });\n });\n }\n\n protected async downloadFile(uploadId: string) {\n const baseUrl = this.config.transport.baseUrl;\n const base = typeof baseUrl === 'string' ? baseUrl : (baseUrl as Signal<string>)();\n const url = base.replace(/\\/$/, '') + '/files/' + uploadId;\n const headers = await Promise.resolve(this.config.transport.getAuthHeaders());\n\n const response = await fetch(url, { headers });\n const disposition = response.headers.get('Content-Disposition');\n const name = disposition?.match(/filename=\"?([^\";\\n]+)\"?/)?.[1] ?? uploadId;\n const blob = await response.blob();\n const blobUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = blobUrl;\n a.download = name;\n a.click();\n URL.revokeObjectURL(blobUrl);\n }\n\n protected cancel() {\n this.chatService.chat()?.addToolOutput({\n tool: 'captureFiles',\n toolCallId: this.toolPart().toolCallId,\n output: {\n status: 'canceled',\n message: 'User canceled upload',\n },\n });\n }\n}\n\n@Component({\n selector: 'cortex-file-input',\n template: `<div\n class=\"flex w-full cursor-pointer items-center rounded-lg border border-slate-300 bg-slate-50 transition hover:border-slate-400 focus-within:ring-2 focus-within:ring-slate-300\"\n >\n <button\n type=\"button\"\n (click)=\"fileInput.click()\"\n class=\"m-1 shrink-0 cursor-pointer rounded-md border-0 bg-slate-800 px-3 py-1.5 text-[11px] font-semibold tracking-wide text-slate-100 hover:bg-slate-700\"\n >\n {{ 'translate_choose_file' | translate }}\n </button>\n <span class=\"truncate px-3 text-[12px] text-slate-600\">{{\n value()?.name ?? ('translate_no_file_chosen' | translate)\n }}</span>\n <input #fileInput (change)=\"loadFile($event)\" type=\"file\" class=\"hidden\" />\n </div>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [TranslatePipe],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n multi: true,\n useExisting: forwardRef(() => FileInputComponent),\n },\n ],\n})\nexport class FileInputComponent implements ControlValueAccessor {\n public allowedMimeTypes = input('*/*');\n\n protected readonly value = signal<InputFile | undefined>(undefined);\n protected readonly isDisabled = signal<boolean>(false);\n protected onTouch?: () => void;\n protected readonly isProcessing = signal<boolean>(false);\n\n private onChange?: (value?: InputFile) => void;\n\n writeValue(value?: InputFile) {\n this.value.set(value);\n }\n\n registerOnChange(fn: (value?: InputFile) => void) {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void) {\n this.onTouch = fn;\n }\n\n setDisabledState(isDisabled: boolean) {\n this.isDisabled.set(isDisabled);\n }\n\n protected async loadFile(event: Event) {\n const fileInput = event.target as HTMLInputElement;\n if (fileInput.files?.length !== 1) return;\n const inputFile = fileInput.files[0];\n const result = await convertFileToBase64(inputFile);\n this.updateValue({\n name: result.name,\n bytes: result.bytes,\n });\n }\n\n protected updateValue(value: InputFile) {\n this.value.set(value);\n this.onChange?.(value);\n }\n}\n\nasync function convertFileToBase64(file: File) {\n return new Promise<{\n name: string;\n bytes: string;\n mimeType: string;\n format: string;\n readerResult: string | ArrayBuffer | null;\n }>((resolve, reject) => {\n const tokens = file.name.split('.');\n const format = tokens.length > 1 ? tokens[tokens.length - 1] : '';\n const reader = new FileReader();\n reader.readAsDataURL(file);\n reader.onload = () => {\n const parts = (reader.result as string).split(',');\n const mimeType = parts[0].replace('data:', '').replace(';base64', '');\n resolve({\n name: file.name,\n bytes: parts[1],\n mimeType,\n format,\n readerResult: reader.result,\n });\n };\n reader.onerror = () => reject();\n });\n}\n","@if (outputData(); as output) {\n <!-- ── Result state ── -->\n @if (output.status === 'success') {\n <div\n class=\"overflow-hidden rounded-2xl border border-emerald-200 bg-linear-to-b from-emerald-50/80 to-white\"\n >\n <div class=\"flex items-center gap-3 px-4 py-3 sm:px-5\">\n <div\n class=\"inline-flex size-8 shrink-0 items-center justify-center rounded-lg border border-emerald-200 bg-emerald-100 text-emerald-600\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-4\" fill=\"none\">\n <path\n d=\"M5.5 10.5 L8.5 13.5 L14.5 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n <div class=\"min-w-0\">\n <h3 class=\"text-[13px] font-semibold tracking-tight text-emerald-800\">\n {{ 'translate_files_attached' | translate: { count: data().files.length } }}\n </h3>\n </div>\n </div>\n\n <div class=\"border-t border-emerald-100 px-4 py-2.5 sm:px-5\">\n <ul class=\"flex flex-wrap gap-2\">\n @for (file of outputData()!.result!; track file.uploadId) {\n <li>\n <button\n type=\"button\"\n (click)=\"downloadFile(file.uploadId)\"\n class=\"inline-flex cursor-pointer items-center gap-1.5 rounded-lg border border-emerald-100 bg-white px-2.5 py-1.5 text-[12px] font-medium text-emerald-700 shadow-xs transition-all hover:border-emerald-200 hover:bg-emerald-50 hover:shadow-sm active:scale-[0.97]\"\n >\n <svg viewBox=\"0 0 16 16\" class=\"size-3.5 shrink-0 text-emerald-400\" fill=\"none\">\n <path\n d=\"M4 1.5h5.172a2 2 0 0 1 1.414.586l2.328 2.328a2 2 0 0 1 .586 1.414V12.5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n />\n <path\n d=\"M9.5 1.5v2a2 2 0 0 0 2 2h2\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n />\n </svg>\n <span class=\"truncate max-w-[180px]\">{{ data().files[$index].label }}</span>\n <svg viewBox=\"0 0 16 16\" class=\"size-3 shrink-0 text-emerald-300\" fill=\"none\">\n <path\n d=\"M8 3v7m0 0L5.5 7.5M8 10l2.5-2.5M3 13h10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n </li>\n }\n </ul>\n </div>\n </div>\n } @else {\n <!-- Canceled state -->\n <div class=\"flex justify-center\">\n <div\n class=\"inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-slate-50 px-4 py-2.5\"\n >\n <div\n class=\"inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-slate-200 bg-slate-100 text-slate-400\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-3\" fill=\"none\">\n <path d=\"M6 10h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </div>\n <span class=\"text-[13px] font-medium text-slate-400\">{{\n 'translate_file_upload_skipped' | translate\n }}</span>\n </div>\n </div>\n }\n} @else {\n <!-- ── Upload form ── -->\n <form [formGroup]=\"form()\" class=\"w-full\">\n @if (data().files.length === 1) {\n <!-- Single file: minimal inline -->\n <fieldset [formArray]=\"form().controls.files\">\n <div [formGroupName]=\"0\" class=\"rounded-xl border border-slate-200 bg-slate-50 p-3\">\n <label for=\"capture-file-0\" class=\"mb-1.5 block text-[12px] text-slate-500\">\n {{ data().files[0].label }}\n </label>\n <input hidden formControlName=\"id\" />\n <div class=\"flex items-center gap-2\">\n <cortex-file-input id=\"capture-file-0\" formControlName=\"file\" class=\"min-w-0 flex-1\" />\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"shrink-0 text-[12px] font-medium text-slate-400 transition-colors hover:text-slate-600\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"inline-flex shrink-0 items-center rounded-md bg-slate-800 px-3 py-1.5 text-[12px] font-medium text-slate-100 transition-colors hover:bg-slate-700 active:bg-slate-900 disabled:cursor-not-allowed disabled:bg-slate-300\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"mr-1.5 size-3 animate-spin\" viewBox=\"0 0 16 16\" fill=\"none\">\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n class=\"opacity-25\"\n />\n <path\n d=\"M14 8a6 6 0 0 0-6-6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ 'translate_uploading' | translate }}\n } @else {\n {{ 'translate_submit' | translate }}\n }\n </button>\n </div>\n </div>\n </fieldset>\n } @else {\n <!-- Multi-file: full form -->\n <div\n class=\"overflow-hidden rounded-2xl border border-slate-200 bg-gradient-to-b from-white to-slate-50\"\n >\n <div class=\"border-b border-slate-200 bg-white/85 px-4 py-3 sm:px-5\">\n <div class=\"flex items-start gap-3\">\n <div\n class=\"mt-0.5 inline-flex size-8 shrink-0 items-center justify-center rounded-lg border border-slate-200 bg-slate-100 text-slate-600\"\n aria-hidden=\"true\"\n >\n <svg viewBox=\"0 0 20 20\" class=\"size-4\" fill=\"none\">\n <path\n d=\"M4 13.5a3.5 3.5 0 0 1-.5-6.97 5.002 5.002 0 0 1 9.78-1.03A4.5 4.5 0 0 1 15.5 14\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M10 10v7m0-7-2.5 2.5M10 10l2.5 2.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.4\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n\n <div class=\"min-w-0\">\n <h3 class=\"text-[13px] font-semibold tracking-tight text-slate-800\">\n {{ 'translate_attach_requested_files' | translate }}\n </h3>\n <p class=\"mt-0.5 text-[11px] text-slate-500\">\n {{ 'translate_n_files_required' | translate: { count: data().files.length } }}\n </p>\n </div>\n </div>\n </div>\n\n <fieldset [formArray]=\"form().controls.files\" class=\"grid gap-3 p-4 sm:p-5\">\n @for (file of form().controls.files.value; track $index) {\n <div\n [formGroupName]=\"$index\"\n class=\"rounded-xl border border-slate-200 bg-white p-3 transition-colors hover:border-slate-300\"\n >\n <div class=\"mb-2 flex items-center justify-between gap-2\">\n <label\n [for]=\"'capture-file-' + $index\"\n class=\"block text-[12px] font-medium leading-none text-slate-700\"\n >\n {{ data().files[$index].label }}\n </label>\n <span\n class=\"inline-flex items-center rounded border border-slate-200 bg-slate-50 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-slate-500\"\n >\n {{ 'translate_required' | translate }}\n </span>\n </div>\n\n <input hidden formControlName=\"id\" />\n <cortex-file-input [id]=\"'capture-file-' + $index\" formControlName=\"file\" />\n </div>\n }\n </fieldset>\n\n <div\n class=\"flex items-center justify-end gap-2 border-t border-slate-200 bg-white/90 px-4 py-3 sm:px-5\"\n >\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"inline-flex items-center rounded-md border border-slate-300 bg-white px-3 py-1.5 text-[12px] font-medium text-slate-600 transition-colors hover:bg-slate-50 active:bg-slate-100\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"inline-flex items-center rounded-md bg-slate-800 px-3 py-1.5 text-[12px] font-medium text-slate-100 transition-colors hover:bg-slate-700 active:bg-slate-900 disabled:cursor-not-allowed disabled:bg-slate-300\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"mr-1.5 size-3 animate-spin\" viewBox=\"0 0 16 16\" fill=\"none\">\n <circle\n cx=\"8\"\n cy=\"8\"\n r=\"6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n class=\"opacity-25\"\n />\n <path\n d=\"M14 8a6 6 0 0 0-6-6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ 'translate_uploading' | translate }}\n } @else {\n {{ 'translate_submit_files' | translate }}\n }\n </button>\n </div>\n </div>\n }\n </form>\n}\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ToolUIPart, UIMessage } from 'ai';\nimport { MessageCaptureFilesPartComponent } from '../message-capture-file-part/message-capture-files-part.component';\nimport { CORTEX_CLIENT_CONFIG } from '../../config';\n\nconst STATUS_COUNT = 10;\n\n@Component({\n selector: 'cortex-message-tool-call-animated',\n templateUrl: './message-tool-call-animated.component.html',\n styleUrl: './message-tool-call-animated.component.scss',\n imports: [NgClass, MessageCaptureFilesPartComponent, TranslatePipe],\n host: { class: 'block w-full' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MessageToolCallAnimatedComponent {\n public readonly message = input.required<UIMessage>();\n public readonly toolCallPart = input.required<ToolUIPart>();\n\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n\n protected readonly customComponent = computed(() => {\n const toolName = this.toolCallPart().type;\n const name = toolName?.startsWith('tool-') ? toolName.slice('tool-'.length) : toolName;\n return name ? (this.config.toolComponents?.[name] ?? null) : null;\n });\n\n protected readonly animState = computed(() => {\n const state = this.toolCallPart().state;\n switch (state) {\n case 'input-streaming':\n return 'starting';\n case 'input-available':\n case 'approval-requested':\n case 'approval-responded':\n return 'processing';\n case 'output-available':\n return 'complete';\n case 'output-error':\n return 'error';\n case 'output-denied':\n return 'denied';\n default:\n return 'processing';\n }\n });\n\n protected readonly isActive = computed(() => {\n const s = this.animState();\n return s === 'starting' || s === 'processing';\n });\n\n protected readonly displayTitleKey = computed(() => {\n const state = this.animState();\n switch (state) {\n case 'starting':\n case 'processing':\n return `translate_tool_status_${this.stableIndex()}`;\n case 'complete':\n return `translate_tool_done_${this.stableIndex()}`;\n case 'error':\n return 'translate_tool_error';\n case 'denied':\n return 'translate_tool_denied';\n default:\n return `translate_tool_status_${this.stableIndex()}`;\n }\n });\n\n private readonly stableIndex = computed(() => {\n const id = this.toolCallPart().toolCallId ?? '';\n let hash = 0;\n for (let i = 0; i < id.length; i++) {\n hash = (hash * 31 + id.charCodeAt(i)) | 0;\n }\n return Math.abs(hash) % STATUS_COUNT;\n });\n}\n","@if (customComponent(); as custom) {\n <ng-container\n *ngComponentOutlet=\"custom; inputs: { toolCallPart: toolCallPart(), message: message() }\"\n />\n} @else {\n @switch (toolCallPart().type) {\n @case ('tool-captureFiles') {\n <cortex-message-capture-files-part [toolPart]=\"toolCallPart()\" [message]=\"message()\" />\n }\n @default {\n @let state = animState();\n @let active = isActive();\n\n <div class=\"flex justify-center\">\n <div\n class=\"inline-flex items-center gap-2.5 py-2.5 px-4 rounded-lg border relative overflow-hidden transition-colors duration-300\"\n [ngClass]=\"{\n 'border-indigo-200 bg-indigo-50': active,\n 'border-emerald-200 bg-emerald-50': state === 'complete',\n 'border-red-200 bg-red-50': state === 'error',\n 'border-slate-200 bg-slate-50 opacity-60': state === 'denied',\n }\"\n >\n <!-- Icon box -->\n <div\n class=\"relative size-6 flex items-center justify-center rounded-md border shrink-0 transition-colors duration-300\"\n [ngClass]=\"{\n 'bg-indigo-100 border-indigo-200': active,\n 'bg-emerald-100 border-emerald-200': state === 'complete',\n 'bg-red-100 border-red-200': state === 'error',\n 'bg-slate-100 border-slate-200': state === 'denied',\n }\"\n >\n <!-- Spinner -->\n <div\n class=\"absolute size-3 border-[1.5px] border-indigo-200 border-t-indigo-500 rounded-full animate-spin transition-opacity duration-200\"\n [ngClass]=\"active ? 'opacity-100' : 'opacity-0'\"\n ></div>\n <!-- Check -->\n <svg\n class=\"absolute size-3 transition-all duration-200\"\n [ngClass]=\"\n state === 'complete'\n ? 'opacity-100 scale-100 text-emerald-600'\n : 'opacity-0 scale-[0.6]'\n \"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M5.5 10.5 L8.5 13.5 L14.5 7\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n <!-- Error -->\n <svg\n class=\"absolute size-3 transition-all duration-200\"\n [ngClass]=\"\n state === 'error' ? 'opacity-100 scale-100 text-red-600' : 'opacity-0 scale-[0.6]'\n \"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M6.5 6.5 L13.5 13.5 M13.5 6.5 L6.5 13.5\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n <!-- Denied -->\n <svg\n class=\"absolute size-3 transition-all duration-200\"\n [ngClass]=\"\n state === 'denied'\n ? 'opacity-100 scale-100 text-slate-400'\n : 'opacity-0 scale-[0.6]'\n \"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M6 10 L14 10\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n\n <!-- Title -->\n <span\n class=\"text-[13px] font-medium whitespace-nowrap overflow-hidden text-ellipsis transition-colors duration-300\"\n [ngClass]=\"{\n 'text-indigo-700': active,\n 'text-emerald-700': state === 'complete',\n 'text-red-600': state === 'error',\n 'text-slate-400': state === 'denied',\n }\"\n >\n {{ displayTitleKey() | translate }}\n </span>\n\n <!-- Bottom bar -->\n <div class=\"absolute bottom-0 inset-x-0 h-0.5 overflow-hidden\">\n <div\n class=\"h-full w-full origin-left\"\n [ngClass]=\"{\n 'bg-indigo-400 animate-bar-slide': active,\n 'bg-emerald-400 animate-bar-fill': state === 'complete',\n 'bg-red-400 animate-bar-fill': state === 'error',\n 'opacity-0': state === 'denied',\n }\"\n ></div>\n </div>\n </div>\n </div>\n }\n }\n}\n","import { NgClass } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { ReasoningUIPart } from 'ai';\n\n@Component({\n selector: 'cortex-message-reasoning-animated',\n templateUrl: './message-reasoning-animated.component.html',\n styleUrl: './message-reasoning-animated.component.scss',\n imports: [NgClass, TranslatePipe],\n host: { class: 'flex justify-center' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MessageReasoningAnimatedComponent {\n public readonly reasoningPart = input.required<ReasoningUIPart>();\n}\n","@let p = reasoningPart();\n@let streaming = p.state === 'streaming';\n\n<div\n class=\"inline-flex items-center gap-2.5 py-2 pl-3 pr-4 rounded-lg border transition-colors duration-300\"\n [ngClass]=\"streaming ? 'border-indigo-200 bg-indigo-50' : 'border-slate-200 bg-slate-50'\"\n>\n <div class=\"flex items-center gap-1\">\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n ></span>\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n [style.animation-delay]=\"streaming ? '200ms' : '0ms'\"\n ></span>\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n [style.animation-delay]=\"streaming ? '400ms' : '0ms'\"\n ></span>\n <span\n class=\"size-[5px] rounded-full transition-all duration-400\"\n [ngClass]=\"streaming ? 'animate-dot-pulse bg-indigo-300' : 'bg-slate-300 opacity-40'\"\n [style.animation-delay]=\"streaming ? '600ms' : '0ms'\"\n ></span>\n </div>\n\n <span\n class=\"text-[13px] font-medium transition-colors duration-300\"\n [ngClass]=\"streaming ? 'text-indigo-600' : 'text-slate-400'\"\n >\n {{ streaming ? ('translate_thinking' | translate) : ('translate_reasoned' | translate) }}\n </span>\n</div>\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { UIDataTypes, UIMessage, UIMessagePart, UITools, isStaticToolUIPart } from 'ai';\nimport { MessageTextPartComponent } from '../message-text-part/message-text-part.component';\nimport { MessageReasoningPartComponent } from '../message-reasoning-part/message-reasoning-part.component';\nimport { MessageToolCallPartComponent } from '../message-tool-call-part/message-tool-call-part.component';\nimport { MessageToolCallAnimatedComponent } from '../message-tool-call-animated/message-tool-call-animated.component';\nimport { MessageReasoningAnimatedComponent } from '../message-reasoning-animated/message-reasoning-animated.component';\nimport { CORTEX_CLIENT_CONFIG } from '../../config';\n\n@Component({\n selector: 'cortex-message-part',\n templateUrl: './message-part.component.html',\n imports: [\n MessageTextPartComponent,\n MessageReasoningPartComponent,\n MessageToolCallPartComponent,\n MessageToolCallAnimatedComponent,\n MessageReasoningAnimatedComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.animate-part-enter]': 'animate()',\n },\n styles: [\n `\n :host {\n @apply empty:hidden block;\n }\n\n :host.animate-part-enter {\n animation: partFadeInUp 0.2s cubic-bezier(0.34, 1.56, 0.64, 1) both;\n }\n\n @keyframes partFadeInUp {\n from {\n opacity: 0;\n transform: translateY(30px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n `,\n ],\n})\nexport class MessagePartComponent {\n public readonly message = input.required<UIMessage>();\n public readonly part = input.required<UIMessagePart<UIDataTypes, UITools>>();\n public readonly debugMode = input<boolean>(false);\n public readonly animate = input<boolean>(false);\n\n private readonly config = inject(CORTEX_CLIENT_CONFIG);\n\n protected readonly isStaticToolUIPart = isStaticToolUIPart;\n\n protected readonly customToolComponent = computed(() => {\n const p = this.part();\n if (!isStaticToolUIPart(p)) return null;\n const toolName = p.type?.startsWith('tool-') ? p.type.slice('tool-'.length) : p.type;\n return toolName ? (this.config.toolComponents?.[toolName] ?? null) : null;\n });\n}\n","@let myPart = part();\n@switch (myPart.type) {\n @case ('text') {\n <cortex-message-text-part [textPart]=\"myPart\" [role]=\"message().role\" />\n }\n @case ('reasoning') {\n @if (debugMode()) {\n <cortex-message-reasoning-part [reasoningPart]=\"myPart\" />\n } @else {\n <cortex-message-reasoning-animated [reasoningPart]=\"myPart\" />\n }\n }\n @default {\n @if (isStaticToolUIPart(myPart)) {\n @if (!debugMode() || customToolComponent()) {\n <cortex-message-tool-call-animated [toolCallPart]=\"myPart\" [message]=\"message()\" />\n } @else {\n <cortex-message-tool-call-part [toolCallPart]=\"myPart\" />\n }\n } @else {\n <p class=\"text-center text-xs text-slate-400\">Unhandled type: {{ part().type }}</p>\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, effect, input, signal } from '@angular/core';\nimport { generateId, UIDataTypes, UIMessage, UIMessagePart, UITools } from 'ai';\nimport { MessagePartComponent } from '../message-part/message-part.component';\n\ntype TrackedPart = UIMessagePart<UIDataTypes, UITools> & { __id: string };\n\n@Component({\n selector: 'cortex-message',\n templateUrl: './message.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MessagePartComponent],\n styles: [\n `\n :host {\n @apply empty:hidden;\n }\n `,\n ],\n})\nexport class MessageComponent {\n public readonly message = input.required<UIMessage>();\n public readonly debugMode = input<boolean>(false);\n public readonly animate = input<boolean>(false);\n\n protected readonly visibleParts = computed(() =>\n this.parts().filter((x) => x.type !== 'step-start'),\n );\n private readonly parts = signal<UIMessagePart<UIDataTypes, UITools>[]>([]);\n\n constructor() {\n effect(() => {\n const parts = this.message().parts;\n\n this.parts.set(parts);\n\n const originalPush = parts.push;\n\n parts.push = (...items) => {\n const newParts = items as unknown as TrackedPart[];\n\n newParts.forEach((x) => (x.__id = generateId()));\n\n this.parts.update((x) => [...x, ...newParts]);\n\n newParts.forEach((part) => {\n Object.keys(part).forEach((prop) => {\n let value = part[prop as keyof typeof part];\n Object.defineProperty(part, prop, {\n get: () => value,\n set: (newValue) => {\n value = newValue;\n this.parts.update((existingParts) => {\n return existingParts.map((x) => {\n return (x as TrackedPart).__id === part.__id ? { ...x, [prop]: newValue } : x;\n });\n });\n },\n configurable: true,\n });\n });\n });\n\n return originalPush.apply(parts, newParts);\n };\n });\n }\n}\n","@if (visibleParts().length) {\n <div class=\"w-full flex flex-col gap-2\">\n @for (part of visibleParts(); track $index) {\n <cortex-message-part\n [part]=\"part\"\n [message]=\"message()\"\n [debugMode]=\"debugMode()\"\n [animate]=\"animate()\"\n />\n }\n </div>\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n effect,\n ElementRef,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { CortexChatService } from '../../services/cortex-chat.service';\nimport { MessageComponent } from '../message/message.component';\n\n@Component({\n selector: 'cortex-message-list',\n templateUrl: './message-list.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MessageComponent],\n})\nexport class MessageListComponent implements AfterViewInit {\n public readonly debugMode = input<boolean>(false);\n private readonly messagesContainer = viewChild<ElementRef>('messagesContainer');\n private shouldScrollToBottom = true;\n private isNearBottom = true;\n\n protected readonly animateNewParts = signal(false);\n\n constructor(\n protected readonly chatService: CortexChatService,\n destroyRef: DestroyRef,\n ) {\n this.scrollToBottom();\n\n effect(() => {\n this.chatService.chat()?.messages;\n\n if (!this.shouldScrollToBottom && !this.isNearBottom) {\n return;\n }\n\n queueMicrotask(() => {\n this.scrollToBottom();\n this.shouldScrollToBottom = false;\n });\n });\n\n chatService.events$.pipe(takeUntilDestroyed(destroyRef)).subscribe((event) => {\n if (event === 'onThreadSelected') {\n this.animateNewParts.set(false);\n this.shouldScrollToBottom = true;\n queueMicrotask(() => this.animateNewParts.set(true));\n }\n if (event === 'onSend') this.shouldScrollToBottom = true;\n });\n }\n\n ngAfterViewInit() {\n queueMicrotask(() => {\n this.scrollToBottom();\n this.shouldScrollToBottom = false;\n this.animateNewParts.set(true);\n });\n }\n\n protected onScroll() {\n const el = this.messagesContainer()?.nativeElement;\n if (!el) return;\n this.isNearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n }\n\n private scrollToBottom() {\n const el = this.messagesContainer()?.nativeElement;\n if (el) {\n el.scrollTop = el.scrollHeight;\n }\n }\n}\n","<div\n class=\"h-full overflow-y-auto w-full flex flex-col gap-2 p-4\"\n #messagesContainer\n (scroll)=\"onScroll()\"\n>\n @for (message of chatService.chat()?.messages; track message.id) {\n <cortex-message [message]=\"message\" [debugMode]=\"debugMode()\" [animate]=\"animateNewParts()\" />\n }\n</div>\n","import { TranslateLoader } from '@ngx-translate/core';\nimport { Observable, of } from 'rxjs';\nimport en from './en.json';\nimport ar from './ar.json';\n\nconst translations: Record<string, Record<string, string>> = { en, ar };\n\nexport class CortexClientTranslateLoader implements TranslateLoader {\n getTranslation(lang: string): Observable<Record<string, string>> {\n return of(translations[lang] ?? translations['en']);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n inject,\n Injectable,\n Injector,\n input,\n model,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { NgClass } from '@angular/common';\nimport {\n provideTranslateLoader,\n provideTranslateService,\n TranslatePipe,\n TranslateService,\n} from '@ngx-translate/core';\nimport { CortexChatService } from '../../services/cortex-chat.service';\nimport { Thread } from '../../services/cortex-chat.service';\nimport { MessageListComponent } from '../message-list/message-list.component';\nimport { CORTEX_CLIENT_CONFIG, CortexClientConfig, CortexClientTheme } from '../../config';\nimport { CortexClientWebSocketService } from '../../services/cortex-websocket.service';\nimport { CortexClientTranslateLoader } from '../../i18n/translate-loader';\n\n@Injectable()\nclass CortexClientConfigRef {\n config!: CortexClientConfig;\n}\n\n@Component({\n selector: 'cortex-chat-widget',\n templateUrl: './chat-widget.component.html',\n styleUrl: './chat-widget.component.scss',\n imports: [NgClass, MessageListComponent, FormsModule, TranslatePipe],\n providers: [\n CortexClientConfigRef,\n {\n provide: CORTEX_CLIENT_CONFIG,\n useFactory: () => inject(CortexClientConfigRef).config,\n },\n CortexChatService,\n CortexClientWebSocketService,\n ...provideTranslateService({\n fallbackLang: 'en',\n loader: provideTranslateLoader(CortexClientTranslateLoader),\n }),\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'block',\n '[style.--cortex-primary-color]': 'theme()?.primaryColor',\n '[style.--cortex-bg-color]': 'theme()?.backgroundColor',\n '[style.--cortex-surface-color]': 'theme()?.surfaceColor',\n '[style.--cortex-text-color]': 'theme()?.textColor',\n '[style.--cortex-border-radius]': 'theme()?.borderRadius',\n },\n})\nexport class CortexChatWidgetComponent {\n public readonly config = input.required<CortexClientConfig>();\n\n protected readonly text = model<string>('');\n protected readonly debugMode = signal(false);\n protected readonly screen = signal<'threads' | 'chat'>('threads');\n protected readonly theme = signal<CortexClientTheme | undefined>(undefined);\n\n protected chatService!: CortexChatService;\n\n private readonly configRef = inject(CortexClientConfigRef);\n private readonly injector = inject(Injector);\n\n ngOnInit() {\n this.configRef.config = this.config();\n this.theme.set(this.config().theme);\n\n this.chatService = this.injector.get(CortexChatService);\n\n const translateService = this.injector.get(TranslateService);\n translateService.use(this.config().locale);\n }\n\n protected toggleDebugMode() {\n this.debugMode.update((v) => !v);\n }\n\n protected selectThread(thread: Thread) {\n this.chatService.selectThread(thread).subscribe();\n this.screen.set('chat');\n }\n\n protected goBack() {\n this.chatService.deselectThread();\n this.screen.set('threads');\n }\n\n protected onKeydown(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.send();\n }\n }\n\n protected send() {\n if (this.chatService.isAgentWorking()) return;\n const text = this.text().trim();\n if (!text) return;\n\n this.text.set('');\n this.chatService.send(text).subscribe();\n }\n\n protected newChat() {\n this.chatService.deselectThread();\n this.screen.set('chat');\n }\n}\n","<div class=\"w-full h-full relative overflow-hidden bg-slate-5\">\n <!-- ═══ SCREEN 1: THREADS ═══ -->\n <div\n class=\"absolute inset-0 flex flex-col transition-transform duration-300 ease-out\"\n [ngClass]=\"\n screen() === 'threads' ? 'translate-x-0' : 'ltr:-translate-x-full rtl:translate-x-full'\n \"\n >\n <!-- Threads header -->\n <div class=\"shrink-0 px-5 pt-5 pb-4 flex items-center justify-between\">\n <div>\n <h2 class=\"text-[15px] font-semibold text-slate-800 tracking-tight\">\n {{ 'translate_threads' | translate }}\n </h2>\n <p class=\"text-[11px] text-slate-400 mt-0.5\">\n {{\n 'translate_n_conversations' | translate: { count: chatService.threads()?.length ?? 0 }\n }}\n </p>\n </div>\n <button\n (click)=\"newChat()\"\n class=\"inline-flex items-center gap-1.5 text-[12px] font-medium text-slate-100 bg-slate-800 px-3 py-1.5 rounded-md hover:bg-slate-700 active:bg-slate-900 transition-colors cursor-pointer\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M8 3v10M3 8h10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n />\n </svg>\n {{ 'translate_new' | translate }}\n </button>\n </div>\n\n <!-- Threads list -->\n <div class=\"flex-1 overflow-y-auto px-3 pb-3\">\n <!-- Threads loading skeleton -->\n @if (chatService.threads() === undefined) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"flex items-center gap-3 px-3 py-3 mb-0.5\">\n <div class=\"skeleton shrink-0 size-8\"></div>\n <div class=\"flex-1 flex flex-col gap-1.5\">\n <div class=\"skeleton h-3.5\" [style.width]=\"40 + i * 12 + '%'\"></div>\n </div>\n </div>\n }\n } @else {\n @for (thread of chatService.threads(); track thread.id) {\n <button\n (click)=\"selectThread(thread)\"\n class=\"group w-full text-start px-3 py-3 rounded-lg flex items-center gap-3 transition-colors cursor-pointer mb-0.5\"\n [ngClass]=\"{\n 'bg-slate-200 text-slate-100': thread.id === chatService.selectedThread()?.id,\n 'text-slate-600 hover:bg-slate-100 active:bg-slate-150':\n thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n <!-- Thread icon -->\n <div\n class=\"shrink-0 size-8 rounded-md flex items-center justify-center text-[11px] font-semibold rtl:transform rtl:rotate-180\"\n [ngClass]=\"{\n 'bg-slate-700 text-slate-300': thread.id === chatService.selectedThread()?.id,\n 'bg-slate-200 text-slate-500': thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M2.5 4.5h11M2.5 8h7M2.5 11.5h9\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n\n <!-- Thread info -->\n <div class=\"min-w-0 flex-1\">\n <p\n class=\"text-[13px] font-medium truncate leading-tight\"\n [ngClass]=\"{\n 'text-slate-100': thread.id === chatService.selectedThread()?.id,\n 'text-slate-700': thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n {{ thread.title ?? ('translate_untitled' | translate) }}\n </p>\n </div>\n\n <!-- Delete button -->\n <button\n (click)=\"$event.stopPropagation(); chatService.deleteThread(thread.id).subscribe()\"\n class=\"shrink-0 opacity-0 group-hover:opacity-100 transition-opacity size-7 rounded-md flex items-center justify-center cursor-pointer\"\n [ngClass]=\"{\n 'hover:bg-slate-600 text-slate-400': thread.id === chatService.selectedThread()?.id,\n 'hover:bg-slate-200 text-slate-400': thread.id !== chatService.selectedThread()?.id,\n }\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M4 4l8 8M12 4l-8 8\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n\n <!-- Arrow -->\n <svg\n class=\"shrink-0 transition-colors rtl:transform rtl:rotate-180\"\n [ngClass]=\"{\n 'text-slate-500': thread.id === chatService.selectedThread()?.id,\n 'text-slate-300 group-hover:text-slate-400':\n thread.id !== chatService.selectedThread()?.id,\n }\"\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n\n @if (!chatService.threads()?.length) {\n <div class=\"flex flex-col items-center justify-center py-16 text-center\">\n <div class=\"size-10 rounded-lg bg-slate-200 flex items-center justify-center mb-3\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 16 16\" fill=\"none\" class=\"text-slate-400\">\n <path\n d=\"M2.5 4.5h11M2.5 8h7M2.5 11.5h9\"\n stroke=\"currentColor\"\n stroke-width=\"1.3\"\n stroke-linecap=\"round\"\n />\n </svg>\n </div>\n <p class=\"text-[13px] text-slate-400 font-medium\">No threads yet</p>\n <p class=\"text-[11px] text-slate-350 mt-1\">Start a new conversation</p>\n </div>\n }\n }\n </div>\n </div>\n\n <!-- ═══ SCREEN 2: CHAT ═══ -->\n <div\n class=\"absolute inset-0 flex flex-col transition-transform duration-300 ease-out\"\n [ngClass]=\"screen() === 'chat' ? 'translate-x-0' : 'ltr:translate-x-full rtl:-translate-x-full'\"\n >\n <!-- Chat header -->\n <div class=\"shrink-0 h-12 px-4 flex items-center gap-3 border-b border-slate-200 bg-white\">\n <!-- Back button -->\n <button\n (click)=\"goBack()\"\n class=\"shrink-0 size-8 rounded-md flex items-center justify-center text-slate-400 hover:text-slate-600 hover:bg-slate-100 transition-colors cursor-pointer\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"rtl:transform rtl:rotate-180\"\n >\n <path\n d=\"M10 3L5 8l5 5\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n\n <!-- Title -->\n <div class=\"min-w-0 flex-1\">\n <p class=\"text-[13px] font-medium text-slate-700 truncate\">\n {{ chatService.selectedThread()?.title ?? ('translate_new_chat' | translate) }}\n </p>\n </div>\n\n <!-- Debug toggle -->\n <button\n (click)=\"toggleDebugMode()\"\n class=\"shrink-0 text-[11px] font-medium px-2.5 py-1 rounded-md transition-colors cursor-pointer\"\n [ngClass]=\"{\n 'bg-amber-50 text-amber-600 hover:bg-amber-100': debugMode(),\n 'bg-slate-100 text-slate-400 hover:bg-slate-200': !debugMode(),\n }\"\n >\n {{ debugMode() ? ('translate_debug' | translate) : ('translate_normal' | translate) }}\n </button>\n </div>\n\n <!-- Messages loading skeleton -->\n @if (chatService.isLoadingMessages() && !chatService.isAgentWorking()) {\n <div class=\"flex-1 overflow-hidden p-4 flex flex-col gap-2\">\n <!-- User message skeleton -->\n <div class=\"w-full flex flex-col items-start\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-bl-none border border-slate-200 bg-slate-50 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-52\"></div>\n <div class=\"skeleton h-3 w-36\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"w-full flex flex-col items-end\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-br-none border border-slate-200 bg-slate-100 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-64\"></div>\n <div class=\"skeleton h-3 w-72\"></div>\n <div class=\"skeleton h-3 w-48\"></div>\n </div>\n </div>\n <!-- User message skeleton -->\n <div class=\"w-full flex flex-col items-start\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-bl-none border border-slate-200 bg-slate-50 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-44\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"w-full flex flex-col items-end\">\n <div\n class=\"max-w-4/5 p-4 rounded-2xl rounded-br-none border border-slate-200 bg-slate-100 flex flex-col gap-2\"\n >\n <div class=\"skeleton h-3 w-56\"></div>\n <div class=\"skeleton h-3 w-60\"></div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Messages area -->\n <cortex-message-list class=\"flex-1 overflow-hidden\" [debugMode]=\"debugMode()\" />\n }\n\n <!-- Agent working indicator -->\n @if (chatService.isAgentWorking() && !chatService.hasPendingToolCalls()) {\n <div class=\"shrink-0 px-4 py-1.5 flex items-center gap-1.5\">\n <div class=\"flex items-center gap-[3px]\">\n <span class=\"cortex-working-dot block size-[5px] rounded-full bg-slate-400\"></span>\n <span class=\"cortex-working-dot block size-[5px] rounded-full bg-slate-400\"></span>\n <span class=\"cortex-working-dot block size-[5px] rounded-full bg-slate-400\"></span>\n </div>\n <span class=\"text-[11px] text-slate-400 font-medium\">{{\n 'translate_thinking' | translate\n }}</span>\n </div>\n }\n\n <!-- Chat input (hidden during pending tool calls) -->\n @if (!chatService.hasPendingToolCalls()) {\n <div class=\"shrink-0 p-3 bg-white border-t border-slate-200\">\n <div\n class=\"flex items-end gap-2 rounded-xl border border-slate-200 p-1.5 transition-colors\"\n [ngClass]=\"{\n 'bg-slate-100': chatService.isAgentWorking(),\n 'bg-slate-50 focus-within:border-slate-300 focus-within:bg-white':\n !chatService.isAgentWorking(),\n }\"\n >\n <textarea\n (keydown)=\"onKeydown($event)\"\n [(ngModel)]=\"text\"\n [placeholder]=\"\n chatService.isAgentWorking() ? '' : ('translate_type_a_message' | translate)\n \"\n [disabled]=\"chatService.isAgentWorking()\"\n rows=\"1\"\n class=\"flex-1 bg-transparent resize-none border-0 outline-none text-[13px] placeholder:text-slate-350 py-1.5 px-2 min-h-[28px] max-h-[120px] leading-snug disabled:cursor-not-allowed disabled:border-0\"\n [ngClass]=\"{\n 'text-slate-400': chatService.isAgentWorking(),\n 'text-slate-700': !chatService.isAgentWorking(),\n }\"\n ></textarea>\n @if (chatService.isAgentWorking()) {\n <!-- Stop button -->\n <button\n (click)=\"chatService.abort()\"\n class=\"stop-btn shrink-0 size-8 rounded-lg flex items-center justify-center cursor-pointer relative\"\n >\n <!-- Pulsing ring -->\n <span class=\"stop-btn-ring absolute inset-0 rounded-lg\"></span>\n <!-- Stop icon (rounded square) -->\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" class=\"relative z-10\">\n <rect x=\"1\" y=\"1\" width=\"10\" height=\"10\" rx=\"2.5\" fill=\"currentColor\" />\n </svg>\n </button>\n } @else {\n <!-- Send button -->\n <button\n (click)=\"send()\"\n class=\"shrink-0 size-8 rounded-lg flex items-center justify-center transition-colors\"\n [ngClass]=\"{\n 'bg-slate-200 text-slate-400': !text().trim(),\n 'bg-slate-800 text-white hover:bg-slate-700 cursor-pointer': text().trim(),\n }\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"rtl:transform rtl:rotate-180\"\n >\n <path\n d=\"M3 8h10M9 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n </div>\n </div>\n }\n </div>\n</div>\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'prettyJson', standalone: true })\nexport class PrettyJsonPipe implements PipeTransform {\n transform(value: unknown) {\n if (value == null) return '';\n const formatted = this.deepFormat(value);\n return JSON.stringify(formatted, null, 2).replace(/\\\\n/g, '\\n');\n }\n\n private deepFormat(value: unknown): unknown {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const parsed = JSON.parse(trimmed);\n return this.deepFormat(parsed);\n } catch {\n // Not valid JSON, fall through\n }\n }\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => this.deepFormat(item));\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = this.deepFormat(val);\n }\n return result;\n }\n\n return value;\n }\n}\n","/*\n * Public API Surface of cortex-client\n */\n\n// Config\nexport type { CortexClientConfig, CortexClientTransport, CortexClientTheme } from './lib/config';\n\n// Services\nexport { CortexChatService } from './lib/services/cortex-chat.service';\nexport type { Thread } from './lib/services/cortex-chat.service';\nexport { CortexClientWebSocketService } from './lib/services/cortex-websocket.service';\n\n// WebSocket events\nexport type { WsEvent, ThreadTitleUpdatedEvent } from './lib/ws-events';\n\n// Components\nexport { CortexChatWidgetComponent } from './lib/components/chat-widget/chat-widget.component';\nexport { MessageListComponent } from './lib/components/message-list/message-list.component';\nexport { MessageComponent } from './lib/components/message/message.component';\nexport { MessagePartComponent } from './lib/components/message-part/message-part.component';\nexport { MessageTextPartComponent } from './lib/components/message-text-part/message-text-part.component';\nexport { MessageToolCallAnimatedComponent } from './lib/components/message-tool-call-animated/message-tool-call-animated.component';\nexport { MessageToolCallPartComponent } from './lib/components/message-tool-call-part/message-tool-call-part.component';\nexport { MessageReasoningPartComponent } from './lib/components/message-reasoning-part/message-reasoning-part.component';\nexport { MessageReasoningAnimatedComponent } from './lib/components/message-reasoning-animated/message-reasoning-animated.component';\nexport {\n MessageCaptureFilesPartComponent,\n FileInputComponent,\n} from './lib/components/message-capture-file-part/message-capture-files-part.component';\nexport { JsonTreeComponent } from './lib/components/json-tree/json-tree.component';\n\n// Pipes\nexport { MarkedPipe } from './lib/pipes/marked.pipe';\nexport { HighlightPipe } from './lib/pipes/highlight.pipe';\nexport { PrettyJsonPipe } from './lib/pipes/pretty-json.pipe';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i1.CortexChatService"],"mappings":"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"}