@m6d/cortex-client 1.5.0 → 1.6.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.
- package/README.md +1 -0
- package/fesm2022/m6d-cortex-client.mjs +455 -138
- package/fesm2022/m6d-cortex-client.mjs.map +1 -1
- package/package.json +1 -1
- package/types/m6d-cortex-client.d.ts +47 -10
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, NgZone, Injectable, signal,
|
|
2
|
+
import { InjectionToken, inject, NgZone, Injectable, signal, computed, DestroyRef, ViewEncapsulation, ChangeDetectionStrategy, Component, Pipe, input, effect, forwardRef, afterNextRender, viewChild, model, Injector } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/forms';
|
|
4
4
|
import { FormControl, Validators, FormBuilder, ReactiveFormsModule, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
5
5
|
import { TranslatePipe, TranslateService, provideTranslateService, provideTranslateLoader } from '@ngx-translate/core';
|
|
6
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
7
|
import { Chat } from '@ai-sdk/angular';
|
|
7
8
|
import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls, isStaticToolUIPart, generateId } from 'ai';
|
|
8
|
-
import { Observable, retry, timer, share,
|
|
9
|
+
import { Subject, Observable, retry, timer, share, of, defer, finalize, tap, switchMap, map } from 'rxjs';
|
|
9
10
|
import { fromPromise } from 'rxjs/internal/observable/innerFrom';
|
|
10
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
11
11
|
import { marked } from 'marked';
|
|
12
12
|
import DOMPurify from 'dompurify';
|
|
13
13
|
import * as i1 from '@angular/platform-browser';
|
|
14
|
-
import { NgClass, NgTemplateOutlet, NgComponentOutlet } from '@angular/common';
|
|
14
|
+
import { NgClass, NgTemplateOutlet, NgComponentOutlet, DecimalPipe, JsonPipe } from '@angular/common';
|
|
15
15
|
import hljs from 'highlight.js/lib/core';
|
|
16
16
|
import javascript from 'highlight.js/lib/languages/javascript';
|
|
17
17
|
import json from 'highlight.js/lib/languages/json';
|
|
@@ -19,19 +19,31 @@ import sql from 'highlight.js/lib/languages/sql';
|
|
|
19
19
|
|
|
20
20
|
const CORTEX_CLIENT_CONFIG = new InjectionToken('CORTEX_CLIENT_CONFIG');
|
|
21
21
|
|
|
22
|
+
function createLatch(count, onComplete) {
|
|
23
|
+
let remaining = count;
|
|
24
|
+
return async () => {
|
|
25
|
+
if (--remaining === 0)
|
|
26
|
+
await onComplete();
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
class CortexClientWebSocketService {
|
|
31
|
+
openedSubject = new Subject();
|
|
23
32
|
events$;
|
|
24
33
|
constructor() {
|
|
25
34
|
const config = inject(CORTEX_CLIENT_CONFIG);
|
|
26
35
|
const ngZone = inject(NgZone);
|
|
27
36
|
this.events$ = new Observable((subscriber) => {
|
|
28
|
-
const wsUrl = config.wsUrl
|
|
37
|
+
const wsUrl = resolveWsUrl(config.wsUrl, config.transport.baseUrl);
|
|
29
38
|
let ws;
|
|
30
39
|
Promise.resolve(config.transport.getAuthHeaders()).then((headers) => {
|
|
31
40
|
if (subscriber.closed)
|
|
32
41
|
return;
|
|
33
42
|
const fullWsUrl = appendTokenToUrl(wsUrl, headers);
|
|
34
43
|
ws = new WebSocket(fullWsUrl);
|
|
44
|
+
ws.addEventListener('open', () => {
|
|
45
|
+
ngZone.run(() => this.openedSubject.next());
|
|
46
|
+
});
|
|
35
47
|
ws.addEventListener('message', (event) => {
|
|
36
48
|
let parsed;
|
|
37
49
|
try {
|
|
@@ -53,12 +65,24 @@ class CortexClientWebSocketService {
|
|
|
53
65
|
get events() {
|
|
54
66
|
return this.events$;
|
|
55
67
|
}
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
get opened() {
|
|
69
|
+
return this.openedSubject.asObservable();
|
|
70
|
+
}
|
|
71
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexClientWebSocketService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
72
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexClientWebSocketService });
|
|
58
73
|
}
|
|
59
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
74
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexClientWebSocketService, decorators: [{
|
|
60
75
|
type: Injectable
|
|
61
76
|
}], ctorParameters: () => [] });
|
|
77
|
+
function resolveWsUrl(wsUrl, baseUrl) {
|
|
78
|
+
const resolvedUrl = wsUrl ?? deriveWsUrl(baseUrl);
|
|
79
|
+
if (!wsUrl)
|
|
80
|
+
return resolvedUrl;
|
|
81
|
+
const agentId = extractAgentId(baseUrl);
|
|
82
|
+
if (!agentId)
|
|
83
|
+
return resolvedUrl;
|
|
84
|
+
return appendAgentIdToUrl(resolvedUrl, agentId);
|
|
85
|
+
}
|
|
62
86
|
function deriveWsUrl(baseUrl) {
|
|
63
87
|
const url = typeof baseUrl === 'string' ? baseUrl : baseUrl();
|
|
64
88
|
const parsed = new URL(url, window.location.origin);
|
|
@@ -66,13 +90,36 @@ function deriveWsUrl(baseUrl) {
|
|
|
66
90
|
parsed.pathname = parsed.pathname.replace(/\/$/, '') + '/ws';
|
|
67
91
|
return parsed.toString();
|
|
68
92
|
}
|
|
93
|
+
function extractAgentId(baseUrl) {
|
|
94
|
+
const url = typeof baseUrl === 'string' ? baseUrl : baseUrl();
|
|
95
|
+
const parsed = new URL(url, window.location.origin);
|
|
96
|
+
const segments = parsed.pathname.split('/').filter(Boolean);
|
|
97
|
+
const agentsIndex = segments.lastIndexOf('agents');
|
|
98
|
+
if (agentsIndex === -1)
|
|
99
|
+
return undefined;
|
|
100
|
+
return segments[agentsIndex + 1];
|
|
101
|
+
}
|
|
102
|
+
function appendAgentIdToUrl(wsUrl, agentId) {
|
|
103
|
+
const parsed = new URL(wsUrl, window.location.origin);
|
|
104
|
+
if (parsed.searchParams.has('agentId') || hasAgentIdInPath(parsed))
|
|
105
|
+
return parsed.toString();
|
|
106
|
+
parsed.searchParams.set('agentId', agentId);
|
|
107
|
+
return parsed.toString();
|
|
108
|
+
}
|
|
109
|
+
function hasAgentIdInPath(url) {
|
|
110
|
+
const segments = url.pathname.split('/').filter(Boolean);
|
|
111
|
+
const agentsIndex = segments.lastIndexOf('agents');
|
|
112
|
+
return agentsIndex !== -1 && Boolean(segments[agentsIndex + 1]);
|
|
113
|
+
}
|
|
69
114
|
function appendTokenToUrl(wsUrl, headers) {
|
|
70
115
|
const authHeader = headers['Authorization'] ?? headers['authorization'];
|
|
71
116
|
if (!authHeader?.startsWith('Bearer '))
|
|
72
117
|
return wsUrl;
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
118
|
+
const parsed = new URL(wsUrl, window.location.origin);
|
|
119
|
+
if (parsed.searchParams.has('token'))
|
|
120
|
+
return parsed.toString();
|
|
121
|
+
parsed.searchParams.set('token', authHeader.slice(7));
|
|
122
|
+
return parsed.toString();
|
|
76
123
|
}
|
|
77
124
|
|
|
78
125
|
class CortexChatService {
|
|
@@ -80,23 +127,34 @@ class CortexChatService {
|
|
|
80
127
|
selectedThread = signal(undefined, ...(ngDevMode ? [{ debugName: "selectedThread" }] : /* istanbul ignore next */ []));
|
|
81
128
|
chat = signal(undefined, ...(ngDevMode ? [{ debugName: "chat" }] : /* istanbul ignore next */ []));
|
|
82
129
|
isLoadingMessages = signal(false, ...(ngDevMode ? [{ debugName: "isLoadingMessages" }] : /* istanbul ignore next */ []));
|
|
83
|
-
isAgentWorking =
|
|
130
|
+
isAgentWorking = computed(() => {
|
|
131
|
+
const chat = this.chat();
|
|
132
|
+
if (!chat)
|
|
133
|
+
return false;
|
|
134
|
+
const status = chat.status;
|
|
135
|
+
return status === 'submitted' || status === 'streaming';
|
|
136
|
+
}, ...(ngDevMode ? [{ debugName: "isAgentWorking" }] : /* istanbul ignore next */ []));
|
|
84
137
|
hasPendingToolCalls = signal(false, ...(ngDevMode ? [{ debugName: "hasPendingToolCalls" }] : /* istanbul ignore next */ []));
|
|
85
138
|
events = new Subject();
|
|
86
139
|
activeThreadSelectionId = 0;
|
|
140
|
+
completeLatchThreadId = undefined;
|
|
141
|
+
hasSeenWsOpen = false;
|
|
87
142
|
config = inject(CORTEX_CLIENT_CONFIG);
|
|
88
143
|
wsService = inject(CortexClientWebSocketService);
|
|
89
144
|
destroyRef = inject(DestroyRef);
|
|
145
|
+
completeLatch = undefined;
|
|
90
146
|
constructor() {
|
|
91
147
|
this.reloadThreads().subscribe();
|
|
92
148
|
this.subscribeToWsEvents();
|
|
149
|
+
this.subscribeToWsConnections();
|
|
93
150
|
}
|
|
94
151
|
get events$() {
|
|
95
152
|
return this.events.asObservable();
|
|
96
153
|
}
|
|
97
154
|
selectThread(thread, options) {
|
|
98
|
-
if (this.selectedThread()?.id === thread.id && this.chat() && !this.isLoadingMessages())
|
|
155
|
+
if (this.selectedThread()?.id === thread.id && this.chat() && !this.isLoadingMessages()) {
|
|
99
156
|
return of();
|
|
157
|
+
}
|
|
100
158
|
const selectionId = ++this.activeThreadSelectionId;
|
|
101
159
|
return (options?.skipLoadingMessages
|
|
102
160
|
? of([])
|
|
@@ -131,22 +189,26 @@ class CortexChatService {
|
|
|
131
189
|
output,
|
|
132
190
|
});
|
|
133
191
|
},
|
|
134
|
-
onError: () => {
|
|
135
|
-
this.isAgentWorking.set(false);
|
|
192
|
+
onError: async () => {
|
|
136
193
|
this.hasPendingToolCalls.set(false);
|
|
137
194
|
this.events.next('onError');
|
|
195
|
+
await this.completeLatch?.();
|
|
138
196
|
},
|
|
139
|
-
onFinish: () => {
|
|
140
|
-
this.isAgentWorking.set(false);
|
|
197
|
+
onFinish: async () => {
|
|
141
198
|
this.hasPendingToolCalls.set(this.hasIncompleteToolCalls(chat.messages));
|
|
142
199
|
this.events.next('onFinish');
|
|
200
|
+
if (this.completeLatch) {
|
|
201
|
+
await this.completeLatch();
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
this.onThreadMessagesUpdated({ threadId: thread.id });
|
|
205
|
+
}
|
|
143
206
|
},
|
|
144
|
-
messages
|
|
207
|
+
messages,
|
|
145
208
|
transport: new DefaultChatTransport({
|
|
146
209
|
api: this.resolveUrl('/chat'),
|
|
147
210
|
headers: async () => await this.resolveHeaders(),
|
|
148
211
|
prepareSendMessagesRequest: ({ messages, id, body, ...rest }) => {
|
|
149
|
-
this.isAgentWorking.set(true);
|
|
150
212
|
this.hasPendingToolCalls.set(false);
|
|
151
213
|
return {
|
|
152
214
|
...rest,
|
|
@@ -163,15 +225,20 @@ class CortexChatService {
|
|
|
163
225
|
this.chat.set(chat);
|
|
164
226
|
this.selectedThread.set(thread);
|
|
165
227
|
this.syncConversationState(messages);
|
|
228
|
+
this.resumeChat(thread.id, {
|
|
229
|
+
reloadMessagesFirst: false,
|
|
230
|
+
reloadMessagesAfterResume: false,
|
|
231
|
+
});
|
|
166
232
|
this.events.next('onThreadSelected');
|
|
167
233
|
}));
|
|
168
234
|
}
|
|
169
235
|
deselectThread() {
|
|
170
236
|
this.activeThreadSelectionId += 1;
|
|
171
|
-
this.
|
|
237
|
+
this.chat()?.stop();
|
|
172
238
|
this.isLoadingMessages.set(false);
|
|
173
|
-
this.isAgentWorking.set(false);
|
|
174
239
|
this.hasPendingToolCalls.set(false);
|
|
240
|
+
this.completeLatch = undefined;
|
|
241
|
+
this.completeLatchThreadId = undefined;
|
|
175
242
|
if (!this.selectedThread() && !this.chat())
|
|
176
243
|
return;
|
|
177
244
|
this.selectedThread.set(undefined);
|
|
@@ -181,38 +248,87 @@ class CortexChatService {
|
|
|
181
248
|
if (this.isAgentWorking() || this.hasPendingToolCalls())
|
|
182
249
|
return of();
|
|
183
250
|
const ensureThread = this.selectedThread()
|
|
184
|
-
? of(
|
|
251
|
+
? of(this.selectedThread().id)
|
|
185
252
|
: fromPromise(this.fetchJson('/threads', {
|
|
186
253
|
method: 'POST',
|
|
187
254
|
body: JSON.stringify({ prompt }),
|
|
188
|
-
})).pipe(switchMap((thread) => this.selectThread(thread, { skipLoadingMessages: true }).pipe(map(() =>
|
|
189
|
-
return ensureThread.pipe(
|
|
255
|
+
})).pipe(tap((thread) => this.upsertThread(thread)), switchMap((thread) => this.selectThread(thread, { skipLoadingMessages: true }).pipe(map(() => thread.id))));
|
|
256
|
+
return ensureThread.pipe(tap((threadId) => {
|
|
257
|
+
this.events.next('onSend');
|
|
258
|
+
this.updateThreadRunning(threadId, true);
|
|
259
|
+
this.completeLatchThreadId = threadId;
|
|
260
|
+
this.completeLatch = createLatch(2, () => {
|
|
261
|
+
this.onThreadMessagesUpdated({ threadId });
|
|
262
|
+
this.completeLatch = undefined;
|
|
263
|
+
this.completeLatchThreadId = undefined;
|
|
264
|
+
});
|
|
265
|
+
}), switchMap(() => fromPromise(this.chat().sendMessage({ text: prompt }))));
|
|
190
266
|
}
|
|
191
267
|
abort() {
|
|
192
268
|
const chat = this.chat();
|
|
193
269
|
if (!chat || !this.isAgentWorking())
|
|
194
270
|
return;
|
|
271
|
+
const threadId = this.selectedThread()?.id;
|
|
272
|
+
if (threadId) {
|
|
273
|
+
this.updateThreadRunning(threadId, false);
|
|
274
|
+
this.fetchJson(`/chat/${threadId}/abort`, { method: 'POST' }).catch(() => { });
|
|
275
|
+
}
|
|
195
276
|
chat.stop();
|
|
196
|
-
this.isAgentWorking.set(false);
|
|
197
277
|
this.hasPendingToolCalls.set(false);
|
|
198
278
|
}
|
|
199
279
|
deleteThread(threadId) {
|
|
200
|
-
if (this.selectedThread()?.id === threadId)
|
|
280
|
+
if (this.selectedThread()?.id === threadId) {
|
|
201
281
|
this.deselectThread();
|
|
202
|
-
|
|
282
|
+
}
|
|
283
|
+
return fromPromise(this.fetchJson(`/threads/${threadId}`, { method: 'DELETE' })).pipe(tap(() => this.removeThread(threadId)));
|
|
203
284
|
}
|
|
204
285
|
subscribeToWsEvents() {
|
|
205
|
-
this.wsService.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
|
|
286
|
+
this.wsService.events.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async (event) => {
|
|
206
287
|
switch (event.type) {
|
|
288
|
+
case 'thread:created':
|
|
289
|
+
this.upsertThread(event.payload.thread);
|
|
290
|
+
break;
|
|
291
|
+
case 'thread:deleted':
|
|
292
|
+
this.onThreadDeleted(event.payload);
|
|
293
|
+
break;
|
|
207
294
|
case 'thread:title-updated':
|
|
208
295
|
this.onThreadTitleUpdated(event.payload);
|
|
209
296
|
break;
|
|
297
|
+
case 'thread:run-started':
|
|
298
|
+
await this.onThreadRunStarted(event.payload);
|
|
299
|
+
break;
|
|
300
|
+
case 'thread:run-finished':
|
|
301
|
+
this.onThreadRunFinished(event.payload);
|
|
302
|
+
break;
|
|
210
303
|
case 'thread:messages-updated':
|
|
211
|
-
this.
|
|
304
|
+
this.upsertThread(event.payload.thread);
|
|
305
|
+
if (this.completeLatch && this.completeLatchThreadId === event.payload.threadId) {
|
|
306
|
+
await this.completeLatch();
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
this.onThreadMessagesUpdated(event.payload);
|
|
310
|
+
}
|
|
212
311
|
break;
|
|
213
312
|
}
|
|
214
313
|
});
|
|
215
314
|
}
|
|
315
|
+
subscribeToWsConnections() {
|
|
316
|
+
this.wsService.opened.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
317
|
+
if (!this.hasSeenWsOpen) {
|
|
318
|
+
this.hasSeenWsOpen = true;
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
this.reloadThreads().subscribe(() => {
|
|
322
|
+
const threadId = this.selectedThread()?.id;
|
|
323
|
+
if (!threadId || this.isAgentWorking())
|
|
324
|
+
return;
|
|
325
|
+
this.resumeChat(threadId, {
|
|
326
|
+
reloadMessagesFirst: true,
|
|
327
|
+
reloadMessagesAfterResume: true,
|
|
328
|
+
});
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
}
|
|
216
332
|
onThreadMessagesUpdated(payload) {
|
|
217
333
|
const chat = this.chat();
|
|
218
334
|
if (!chat || this.selectedThread()?.id !== payload.threadId)
|
|
@@ -228,24 +344,108 @@ class CortexChatService {
|
|
|
228
344
|
this.syncConversationState(messages);
|
|
229
345
|
});
|
|
230
346
|
}
|
|
347
|
+
async onThreadRunStarted(payload) {
|
|
348
|
+
this.upsertThread(payload.thread);
|
|
349
|
+
if (this.selectedThread()?.id !== payload.thread.id || this.isAgentWorking())
|
|
350
|
+
return;
|
|
351
|
+
await this.resumeChat(payload.thread.id, {
|
|
352
|
+
reloadMessagesFirst: true,
|
|
353
|
+
reloadMessagesAfterResume: true,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
231
356
|
onThreadTitleUpdated(payload) {
|
|
357
|
+
this.upsertThread(payload.thread);
|
|
358
|
+
}
|
|
359
|
+
onThreadRunFinished(payload) {
|
|
360
|
+
this.upsertThread(payload.thread);
|
|
361
|
+
}
|
|
362
|
+
onThreadDeleted(payload) {
|
|
363
|
+
this.removeThread(payload.threadId);
|
|
364
|
+
if (this.selectedThread()?.id !== payload.threadId)
|
|
365
|
+
return;
|
|
366
|
+
this.deselectThread();
|
|
367
|
+
}
|
|
368
|
+
upsertThread(thread) {
|
|
232
369
|
const current = this.threads();
|
|
233
|
-
|
|
234
|
-
|
|
370
|
+
const nextThreads = current ? [...current] : [];
|
|
371
|
+
const existingIndex = nextThreads.findIndex((currentThread) => currentThread.id === thread.id);
|
|
372
|
+
if (existingIndex === -1) {
|
|
373
|
+
nextThreads.push(thread);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
nextThreads[existingIndex] = { ...nextThreads[existingIndex], ...thread };
|
|
235
377
|
}
|
|
378
|
+
this.threads.set(this.sortThreads(nextThreads));
|
|
236
379
|
const selected = this.selectedThread();
|
|
237
|
-
if (selected?.id ===
|
|
238
|
-
this.selectedThread.set({ ...selected,
|
|
380
|
+
if (selected?.id === thread.id) {
|
|
381
|
+
this.selectedThread.set({ ...selected, ...thread });
|
|
239
382
|
}
|
|
240
383
|
}
|
|
384
|
+
removeThread(threadId) {
|
|
385
|
+
const current = this.threads();
|
|
386
|
+
if (!current)
|
|
387
|
+
return;
|
|
388
|
+
this.threads.set(current.filter((thread) => thread.id !== threadId));
|
|
389
|
+
}
|
|
390
|
+
updateThreadRunning(threadId, isRunning) {
|
|
391
|
+
const thread = this.threads()?.find((currentThread) => currentThread.id === threadId);
|
|
392
|
+
if (thread) {
|
|
393
|
+
this.upsertThread({ ...thread, isRunning });
|
|
394
|
+
}
|
|
395
|
+
const selected = this.selectedThread();
|
|
396
|
+
if (selected?.id === threadId) {
|
|
397
|
+
this.selectedThread.set({ ...selected, isRunning });
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
sortThreads(threads) {
|
|
401
|
+
return [...threads].sort((left, right) => {
|
|
402
|
+
const updatedAtDelta = Date.parse(right.updatedAt) - Date.parse(left.updatedAt);
|
|
403
|
+
if (updatedAtDelta !== 0)
|
|
404
|
+
return updatedAtDelta;
|
|
405
|
+
return Date.parse(right.createdAt) - Date.parse(left.createdAt);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
async resumeChat(threadId, options) {
|
|
409
|
+
const chat = this.chat();
|
|
410
|
+
if (!chat || this.selectedThread()?.id !== threadId)
|
|
411
|
+
return;
|
|
412
|
+
if (options.reloadMessagesFirst) {
|
|
413
|
+
try {
|
|
414
|
+
await this.reloadMessagesForSelectedThread(threadId);
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
if (this.chat() !== chat || this.selectedThread()?.id !== threadId)
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
void chat.resumeStream().then(() => {
|
|
423
|
+
if (this.chat() !== chat || this.selectedThread()?.id !== threadId)
|
|
424
|
+
return;
|
|
425
|
+
if (this.isAgentWorking())
|
|
426
|
+
return;
|
|
427
|
+
if (!options.reloadMessagesAfterResume)
|
|
428
|
+
return;
|
|
429
|
+
this.reloadMessagesForSelectedThread(threadId).catch(() => { });
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
async reloadMessagesForSelectedThread(threadId) {
|
|
433
|
+
const chat = this.chat();
|
|
434
|
+
if (!chat || this.selectedThread()?.id !== threadId)
|
|
435
|
+
return;
|
|
436
|
+
const messages = await this.fetchJson(`/threads/${threadId}/messages`);
|
|
437
|
+
if (this.chat() !== chat || this.selectedThread()?.id !== threadId)
|
|
438
|
+
return;
|
|
439
|
+
chat.messages = messages;
|
|
440
|
+
this.syncConversationState(messages);
|
|
441
|
+
}
|
|
241
442
|
reloadThreads() {
|
|
242
|
-
return fromPromise(this.fetchJson('/threads')).pipe(tap((threads) => this.threads.set(threads)));
|
|
443
|
+
return fromPromise(this.fetchJson('/threads')).pipe(tap((threads) => this.threads.set(this.sortThreads(threads))));
|
|
243
444
|
}
|
|
244
445
|
reloadMessages(threadId) {
|
|
245
446
|
return fromPromise(this.fetchJson(`/threads/${threadId}/messages`));
|
|
246
447
|
}
|
|
247
448
|
syncConversationState(messages) {
|
|
248
|
-
this.isAgentWorking.set(false);
|
|
249
449
|
this.hasPendingToolCalls.set(this.hasIncompleteToolCalls(messages));
|
|
250
450
|
}
|
|
251
451
|
hasIncompleteToolCalls(messages) {
|
|
@@ -301,10 +501,10 @@ class CortexChatService {
|
|
|
301
501
|
const text = await res.text();
|
|
302
502
|
return text ? JSON.parse(text) : undefined;
|
|
303
503
|
}
|
|
304
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
305
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
504
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexChatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
505
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexChatService });
|
|
306
506
|
}
|
|
307
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
507
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexChatService, decorators: [{
|
|
308
508
|
type: Injectable
|
|
309
509
|
}], ctorParameters: () => [] });
|
|
310
510
|
/**
|
|
@@ -328,6 +528,15 @@ function fixChat(chat) {
|
|
|
328
528
|
chat.state.snapshot = deepClone;
|
|
329
529
|
}
|
|
330
530
|
|
|
531
|
+
class MessageAbortedFlagComponent {
|
|
532
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageAbortedFlagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
533
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: MessageAbortedFlagComponent, isStandalone: true, selector: "cortex-message-aborted-flag", host: { classAttribute: "cortex-aborted-flag" }, ngImport: i0, template: "<span class=\"cortex-aborted-flag__line\"></span>\n<span class=\"cortex-aborted-flag__label\">\n <svg class=\"cortex-aborted-flag__icon\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M6 1.5v5M6 8.75v.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" />\n </svg>\n {{ 'translate_aborted' | translate }}\n</span>\n<span class=\"cortex-aborted-flag__line\"></span>\n", styles: ["@keyframes cortex-aborted-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.cortex-aborted-flag{display:flex;align-items:center;gap:.625rem;padding:.25rem 0;animation:cortex-aborted-fade-in .3s ease-out both;-webkit-user-select:none;user-select:none}.cortex-aborted-flag__line{flex:1;height:1px;background:repeating-linear-gradient(90deg,#e2a36f 0px,#e2a36f 4px,transparent 4px,transparent 8px);opacity:.5}.cortex-aborted-flag__label{display:inline-flex;align-items:center;gap:.3125rem;font-family:SF Mono,Cascadia Code,Fira Code,JetBrains Mono,ui-monospace,monospace;font-size:.625rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#c2824a}.cortex-aborted-flag__icon{color:#c2824a;flex-shrink:0}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
534
|
+
}
|
|
535
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageAbortedFlagComponent, decorators: [{
|
|
536
|
+
type: Component,
|
|
537
|
+
args: [{ selector: 'cortex-message-aborted-flag', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [TranslatePipe], host: { class: 'cortex-aborted-flag' }, template: "<span class=\"cortex-aborted-flag__line\"></span>\n<span class=\"cortex-aborted-flag__label\">\n <svg class=\"cortex-aborted-flag__icon\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path d=\"M6 1.5v5M6 8.75v.5\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" />\n </svg>\n {{ 'translate_aborted' | translate }}\n</span>\n<span class=\"cortex-aborted-flag__line\"></span>\n", styles: ["@keyframes cortex-aborted-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.cortex-aborted-flag{display:flex;align-items:center;gap:.625rem;padding:.25rem 0;animation:cortex-aborted-fade-in .3s ease-out both;-webkit-user-select:none;user-select:none}.cortex-aborted-flag__line{flex:1;height:1px;background:repeating-linear-gradient(90deg,#e2a36f 0px,#e2a36f 4px,transparent 4px,transparent 8px);opacity:.5}.cortex-aborted-flag__label{display:inline-flex;align-items:center;gap:.3125rem;font-family:SF Mono,Cascadia Code,Fira Code,JetBrains Mono,ui-monospace,monospace;font-size:.625rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#c2824a}.cortex-aborted-flag__icon{color:#c2824a;flex-shrink:0}\n"] }]
|
|
538
|
+
}] });
|
|
539
|
+
|
|
331
540
|
class MarkedPipe {
|
|
332
541
|
sanitizer;
|
|
333
542
|
constructor(sanitizer) {
|
|
@@ -344,10 +553,10 @@ class MarkedPipe {
|
|
|
344
553
|
.replace(/<(t[hd])([\s>])/g, '<$1 style="padding:0.5rem 1rem"$2');
|
|
345
554
|
return this.sanitizer.bypassSecurityTrustHtml(DOMPurify.sanitize(html));
|
|
346
555
|
}
|
|
347
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
348
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
556
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MarkedPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
557
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.5", ngImport: i0, type: MarkedPipe, isStandalone: true, name: "marked" });
|
|
349
558
|
}
|
|
350
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
559
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MarkedPipe, decorators: [{
|
|
351
560
|
type: Pipe,
|
|
352
561
|
args: [{
|
|
353
562
|
name: 'marked',
|
|
@@ -382,9 +591,15 @@ class StreamTextSmoother {
|
|
|
382
591
|
constructor(onUpdate) {
|
|
383
592
|
this.onUpdate = onUpdate;
|
|
384
593
|
}
|
|
594
|
+
seed(displayedText) {
|
|
595
|
+
this.fullText = displayedText;
|
|
596
|
+
this.displayedLength = displayedText.length;
|
|
597
|
+
this.onUpdate(displayedText);
|
|
598
|
+
}
|
|
385
599
|
update(newFullText, done) {
|
|
386
600
|
this.fullText = newFullText;
|
|
387
601
|
this.isDone = done;
|
|
602
|
+
this.displayedLength = Math.min(this.displayedLength, this.fullText.length);
|
|
388
603
|
if (done && this.displayedLength >= this.fullText.length) {
|
|
389
604
|
this.onUpdate(this.fullText);
|
|
390
605
|
this.stopAnimation();
|
|
@@ -437,23 +652,28 @@ class MessageTextPartComponent {
|
|
|
437
652
|
effect(() => {
|
|
438
653
|
const part = this.textPart();
|
|
439
654
|
const role = this.role();
|
|
655
|
+
const isStreaming = part.state === 'streaming';
|
|
440
656
|
if (role !== 'assistant') {
|
|
441
657
|
this.destroySmoother();
|
|
442
658
|
this.displayedText.set(part.text);
|
|
443
659
|
this.isFirstRender = false;
|
|
444
660
|
return;
|
|
445
661
|
}
|
|
446
|
-
|
|
447
|
-
|
|
662
|
+
if (!isStreaming) {
|
|
663
|
+
this.destroySmoother();
|
|
448
664
|
this.displayedText.set(part.text);
|
|
449
665
|
this.isFirstRender = false;
|
|
450
666
|
return;
|
|
451
667
|
}
|
|
452
|
-
this.isFirstRender
|
|
453
|
-
|
|
454
|
-
this.smoother
|
|
668
|
+
if (this.isFirstRender) {
|
|
669
|
+
this.ensureSmoother();
|
|
670
|
+
this.smoother.seed(part.text);
|
|
671
|
+
this.isFirstRender = false;
|
|
672
|
+
return;
|
|
455
673
|
}
|
|
456
|
-
this.
|
|
674
|
+
this.isFirstRender = false;
|
|
675
|
+
this.ensureSmoother();
|
|
676
|
+
this.smoother.update(part.text, false);
|
|
457
677
|
});
|
|
458
678
|
}
|
|
459
679
|
ngOnDestroy() {
|
|
@@ -465,20 +685,27 @@ class MessageTextPartComponent {
|
|
|
465
685
|
this.smoother = null;
|
|
466
686
|
}
|
|
467
687
|
}
|
|
468
|
-
|
|
469
|
-
|
|
688
|
+
ensureSmoother() {
|
|
689
|
+
if (this.smoother) {
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
this.smoother = new StreamTextSmoother((text) => this.displayedText.set(text));
|
|
693
|
+
this.smoother.seed(this.displayedText());
|
|
694
|
+
}
|
|
695
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageTextPartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
696
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: MessageTextPartComponent, isStandalone: true, selector: "cortex-message-text-part", inputs: { role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: true, transformFunction: null }, textPart: { classPropertyName: "textPart", publicName: "textPart", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"cortex-text-part\"\n [class.cortex-text-part--assistant]=\"role() === 'assistant'\"\n [class.cortex-text-part--user]=\"role() === 'user'\"\n>\n <div\n class=\"cortex-text-bubble\"\n [class.cortex-text-bubble--assistant]=\"role() === 'assistant'\"\n [class.cortex-text-bubble--user]=\"role() === 'user'\"\n [innerHTML]=\"displayedText() | marked\"\n ></div>\n</div>\n", styles: [".cortex-text-part{width:100%;display:flex;flex-direction:column}.cortex-text-part--assistant{align-items:flex-start}.cortex-text-part--user{align-items:flex-end}[dir=rtl] .cortex-text-part--assistant{align-items:flex-start}[dir=rtl] .cortex-text-part--user{align-items:flex-end}.cortex-text-bubble{max-width:80%;font-size:.8125rem;line-height:1.625;padding:1rem;border-radius:1rem;border:1px solid #e2e8f0;color:#334155}.cortex-text-bubble--assistant{background:#f1f5f9;border-bottom-left-radius:0}[dir=rtl] .cortex-text-bubble--assistant{border-bottom-left-radius:1rem;border-bottom-right-radius:0}.cortex-text-bubble--user{background:#f8fafc;border-bottom-right-radius:0}[dir=rtl] .cortex-text-bubble--user{border-bottom-right-radius:1rem;border-bottom-left-radius:0}.cortex-text-bubble h1,.cortex-text-bubble h2,.cortex-text-bubble h3,.cortex-text-bubble h4,.cortex-text-bubble h5,.cortex-text-bubble h6{margin-top:1.25em;margin-bottom:.5em;font-weight:600;line-height:1.3;color:#1e293b}.cortex-text-bubble h1:first-child,.cortex-text-bubble h2:first-child,.cortex-text-bubble h3:first-child,.cortex-text-bubble h4:first-child,.cortex-text-bubble h5:first-child,.cortex-text-bubble h6:first-child{margin-top:0}.cortex-text-bubble h1{font-size:1.25em}.cortex-text-bubble h2{font-size:1.125em}.cortex-text-bubble h3{font-size:1em}.cortex-text-bubble p{margin-top:.75em;margin-bottom:.75em}.cortex-text-bubble p:first-child{margin-top:0}.cortex-text-bubble p:last-child{margin-bottom:0}.cortex-text-bubble ul,.cortex-text-bubble ol{margin-top:.75em;margin-bottom:.75em;padding-inline-start:1.5em}.cortex-text-bubble ul{list-style-type:disc}.cortex-text-bubble ol{list-style-type:decimal}.cortex-text-bubble li{margin-top:.25em;margin-bottom:.25em}.cortex-text-bubble code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875em;background:#e2e8f0;padding:.125em .375em;border-radius:.25rem}.cortex-text-bubble pre{margin-top:.75em;margin-bottom:.75em;padding:.75em 1em;background:#1e293b;border-radius:.5rem;overflow-x:auto;font-size:.8125em;line-height:1.6}.cortex-text-bubble pre code{background:transparent;padding:0;color:#e2e8f0}.cortex-text-bubble blockquote{margin-top:.75em;margin-bottom:.75em;padding-inline-start:1em;border-inline-start:3px solid #cbd5e1;color:#64748b;font-style:italic}.cortex-text-bubble a{color:#2563eb;text-decoration:underline}.cortex-text-bubble a:hover{color:#1d4ed8}.cortex-text-bubble table{width:100%;border-collapse:collapse;margin-top:.75em;margin-bottom:.75em;font-size:.875em}.cortex-text-bubble th,.cortex-text-bubble td{border:1px solid #e2e8f0;padding:.375em .75em;text-align:start}.cortex-text-bubble th{background:#f8fafc;font-weight:600}.cortex-text-bubble hr{margin-top:1.5em;margin-bottom:1.5em;border:none;border-top:1px solid #e2e8f0}.cortex-text-bubble img{max-width:100%;height:auto;border-radius:.375rem}\n"], dependencies: [{ kind: "pipe", type: MarkedPipe, name: "marked" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
470
697
|
}
|
|
471
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
698
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageTextPartComponent, decorators: [{
|
|
472
699
|
type: Component,
|
|
473
700
|
args: [{ selector: 'cortex-message-text-part', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [MarkedPipe], template: "<div\n class=\"cortex-text-part\"\n [class.cortex-text-part--assistant]=\"role() === 'assistant'\"\n [class.cortex-text-part--user]=\"role() === 'user'\"\n>\n <div\n class=\"cortex-text-bubble\"\n [class.cortex-text-bubble--assistant]=\"role() === 'assistant'\"\n [class.cortex-text-bubble--user]=\"role() === 'user'\"\n [innerHTML]=\"displayedText() | marked\"\n ></div>\n</div>\n", styles: [".cortex-text-part{width:100%;display:flex;flex-direction:column}.cortex-text-part--assistant{align-items:flex-start}.cortex-text-part--user{align-items:flex-end}[dir=rtl] .cortex-text-part--assistant{align-items:flex-start}[dir=rtl] .cortex-text-part--user{align-items:flex-end}.cortex-text-bubble{max-width:80%;font-size:.8125rem;line-height:1.625;padding:1rem;border-radius:1rem;border:1px solid #e2e8f0;color:#334155}.cortex-text-bubble--assistant{background:#f1f5f9;border-bottom-left-radius:0}[dir=rtl] .cortex-text-bubble--assistant{border-bottom-left-radius:1rem;border-bottom-right-radius:0}.cortex-text-bubble--user{background:#f8fafc;border-bottom-right-radius:0}[dir=rtl] .cortex-text-bubble--user{border-bottom-right-radius:1rem;border-bottom-left-radius:0}.cortex-text-bubble h1,.cortex-text-bubble h2,.cortex-text-bubble h3,.cortex-text-bubble h4,.cortex-text-bubble h5,.cortex-text-bubble h6{margin-top:1.25em;margin-bottom:.5em;font-weight:600;line-height:1.3;color:#1e293b}.cortex-text-bubble h1:first-child,.cortex-text-bubble h2:first-child,.cortex-text-bubble h3:first-child,.cortex-text-bubble h4:first-child,.cortex-text-bubble h5:first-child,.cortex-text-bubble h6:first-child{margin-top:0}.cortex-text-bubble h1{font-size:1.25em}.cortex-text-bubble h2{font-size:1.125em}.cortex-text-bubble h3{font-size:1em}.cortex-text-bubble p{margin-top:.75em;margin-bottom:.75em}.cortex-text-bubble p:first-child{margin-top:0}.cortex-text-bubble p:last-child{margin-bottom:0}.cortex-text-bubble ul,.cortex-text-bubble ol{margin-top:.75em;margin-bottom:.75em;padding-inline-start:1.5em}.cortex-text-bubble ul{list-style-type:disc}.cortex-text-bubble ol{list-style-type:decimal}.cortex-text-bubble li{margin-top:.25em;margin-bottom:.25em}.cortex-text-bubble code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.875em;background:#e2e8f0;padding:.125em .375em;border-radius:.25rem}.cortex-text-bubble pre{margin-top:.75em;margin-bottom:.75em;padding:.75em 1em;background:#1e293b;border-radius:.5rem;overflow-x:auto;font-size:.8125em;line-height:1.6}.cortex-text-bubble pre code{background:transparent;padding:0;color:#e2e8f0}.cortex-text-bubble blockquote{margin-top:.75em;margin-bottom:.75em;padding-inline-start:1em;border-inline-start:3px solid #cbd5e1;color:#64748b;font-style:italic}.cortex-text-bubble a{color:#2563eb;text-decoration:underline}.cortex-text-bubble a:hover{color:#1d4ed8}.cortex-text-bubble table{width:100%;border-collapse:collapse;margin-top:.75em;margin-bottom:.75em;font-size:.875em}.cortex-text-bubble th,.cortex-text-bubble td{border:1px solid #e2e8f0;padding:.375em .75em;text-align:start}.cortex-text-bubble th{background:#f8fafc;font-weight:600}.cortex-text-bubble hr{margin-top:1.5em;margin-bottom:1.5em;border:none;border-top:1px solid #e2e8f0}.cortex-text-bubble img{max-width:100%;height:auto;border-radius:.375rem}\n"] }]
|
|
474
701
|
}], ctorParameters: () => [], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: true }] }], textPart: [{ type: i0.Input, args: [{ isSignal: true, alias: "textPart", required: true }] }] } });
|
|
475
702
|
|
|
476
703
|
class MessageReasoningPartComponent {
|
|
477
704
|
reasoningPart = input.required(...(ngDevMode ? [{ debugName: "reasoningPart" }] : /* istanbul ignore next */ []));
|
|
478
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
479
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
705
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageReasoningPartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
706
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageReasoningPartComponent, isStandalone: true, selector: "cortex-message-reasoning-part", inputs: { reasoningPart: { classPropertyName: "reasoningPart", publicName: "reasoningPart", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "@let p = reasoningPart();\n<details class=\"cortex-reasoning-details\">\n <summary class=\"cortex-reasoning-details__summary\">\n <div class=\"cortex-reasoning-details__header\">\n <span class=\"cortex-reasoning-details__icon\">\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=\"cortex-reasoning-details__title-group\">\n <div class=\"cortex-reasoning-details__title-row\">\n <div class=\"cortex-reasoning-details__title\">Reasoning</div>\n @if (p.state) {\n <span\n class=\"cortex-reasoning-details__badge\"\n [ngClass]=\"{\n 'cortex-reasoning-details__badge--streaming': p.state === 'streaming',\n 'cortex-reasoning-details__badge--done': p.state === 'done',\n }\"\n >\n {{ p.state === 'streaming' ? 'Streaming' : 'Done' }}\n </span>\n }\n </div>\n </div>\n </div>\n\n <span class=\"cortex-reasoning-details__chevron\" aria-hidden=\"true\">\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=\"cortex-reasoning-details__body\">\n <div class=\"cortex-reasoning-details__content\">\n <pre class=\"cortex-reasoning-details__pre\">{{\n p.text.trim() ? p.text : 'No reasoning provided.'\n }}</pre>\n </div>\n </div>\n</details>\n", styles: [".cortex-reasoning-details{width:100%;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cortex-reasoning-details__summary{list-style:none;cursor:pointer;-webkit-user-select:none;user-select:none;padding:.75rem 1rem;display:flex;align-items:center;gap:.75rem}.cortex-reasoning-details__summary::-webkit-details-marker{display:none}.cortex-reasoning-details__header{display:flex;align-items:center;gap:.5rem;min-width:0;flex:1}.cortex-reasoning-details__icon{display:inline-flex;height:1.5rem;width:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;background:#e0e7ff;color:#4f46e5}.cortex-reasoning-details__title-group{min-width:0}.cortex-reasoning-details__title-row{display:flex;align-items:center;gap:.5rem}.cortex-reasoning-details__title{font-weight:500;color:#334155;font-size:.875rem}.cortex-reasoning-details__badge{display:inline-flex;align-items:center;border-radius:.25rem;padding:.125rem .375rem;font-size:.6875rem;font-weight:500}.cortex-reasoning-details__badge--streaming{background:#fef3c7;color:#b45309}.cortex-reasoning-details__badge--done{background:#d1fae5;color:#047857}.cortex-reasoning-details__chevron{margin-inline-start:auto;display:inline-flex;height:1.5rem;width:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;color:#94a3b8;transition:transform .2s}details[open]>summary>.cortex-reasoning-details__chevron{transform:rotate(180deg)}.cortex-reasoning-details__body{padding:0 1rem 1rem}.cortex-reasoning-details__content{margin-top:.25rem;border-radius:.25rem;background:#fff;border:1px solid #e2e8f0;padding:.75rem}.cortex-reasoning-details__pre{margin:0;white-space:pre-wrap;overflow-wrap:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;line-height:1.625;color:#334155}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
480
707
|
}
|
|
481
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
708
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageReasoningPartComponent, decorators: [{
|
|
482
709
|
type: Component,
|
|
483
710
|
args: [{ selector: 'cortex-message-reasoning-part', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [NgClass], template: "@let p = reasoningPart();\n<details class=\"cortex-reasoning-details\">\n <summary class=\"cortex-reasoning-details__summary\">\n <div class=\"cortex-reasoning-details__header\">\n <span class=\"cortex-reasoning-details__icon\">\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=\"cortex-reasoning-details__title-group\">\n <div class=\"cortex-reasoning-details__title-row\">\n <div class=\"cortex-reasoning-details__title\">Reasoning</div>\n @if (p.state) {\n <span\n class=\"cortex-reasoning-details__badge\"\n [ngClass]=\"{\n 'cortex-reasoning-details__badge--streaming': p.state === 'streaming',\n 'cortex-reasoning-details__badge--done': p.state === 'done',\n }\"\n >\n {{ p.state === 'streaming' ? 'Streaming' : 'Done' }}\n </span>\n }\n </div>\n </div>\n </div>\n\n <span class=\"cortex-reasoning-details__chevron\" aria-hidden=\"true\">\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=\"cortex-reasoning-details__body\">\n <div class=\"cortex-reasoning-details__content\">\n <pre class=\"cortex-reasoning-details__pre\">{{\n p.text.trim() ? p.text : 'No reasoning provided.'\n }}</pre>\n </div>\n </div>\n</details>\n", styles: [".cortex-reasoning-details{width:100%;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cortex-reasoning-details__summary{list-style:none;cursor:pointer;-webkit-user-select:none;user-select:none;padding:.75rem 1rem;display:flex;align-items:center;gap:.75rem}.cortex-reasoning-details__summary::-webkit-details-marker{display:none}.cortex-reasoning-details__header{display:flex;align-items:center;gap:.5rem;min-width:0;flex:1}.cortex-reasoning-details__icon{display:inline-flex;height:1.5rem;width:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;background:#e0e7ff;color:#4f46e5}.cortex-reasoning-details__title-group{min-width:0}.cortex-reasoning-details__title-row{display:flex;align-items:center;gap:.5rem}.cortex-reasoning-details__title{font-weight:500;color:#334155;font-size:.875rem}.cortex-reasoning-details__badge{display:inline-flex;align-items:center;border-radius:.25rem;padding:.125rem .375rem;font-size:.6875rem;font-weight:500}.cortex-reasoning-details__badge--streaming{background:#fef3c7;color:#b45309}.cortex-reasoning-details__badge--done{background:#d1fae5;color:#047857}.cortex-reasoning-details__chevron{margin-inline-start:auto;display:inline-flex;height:1.5rem;width:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;color:#94a3b8;transition:transform .2s}details[open]>summary>.cortex-reasoning-details__chevron{transform:rotate(180deg)}.cortex-reasoning-details__body{padding:0 1rem 1rem}.cortex-reasoning-details__content{margin-top:.25rem;border-radius:.25rem;background:#fff;border:1px solid #e2e8f0;padding:.75rem}.cortex-reasoning-details__pre{margin:0;white-space:pre-wrap;overflow-wrap:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;line-height:1.625;color:#334155}\n"] }]
|
|
484
711
|
}], propDecorators: { reasoningPart: [{ type: i0.Input, args: [{ isSignal: true, alias: "reasoningPart", required: true }] }] } });
|
|
@@ -502,10 +729,10 @@ class HighlightPipe {
|
|
|
502
729
|
escapeHtml(str) {
|
|
503
730
|
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
504
731
|
}
|
|
505
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
506
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.
|
|
732
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: HighlightPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
733
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.5", ngImport: i0, type: HighlightPipe, isStandalone: true, name: "highlight" });
|
|
507
734
|
}
|
|
508
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
735
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: HighlightPipe, decorators: [{
|
|
509
736
|
type: Pipe,
|
|
510
737
|
args: [{ name: 'highlight', standalone: true }]
|
|
511
738
|
}], ctorParameters: () => [{ type: i1.DomSanitizer }] });
|
|
@@ -603,10 +830,10 @@ class JsonTreeComponent {
|
|
|
603
830
|
}
|
|
604
831
|
return value;
|
|
605
832
|
}
|
|
606
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
607
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
833
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: JsonTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
834
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: JsonTreeComponent, isStandalone: true, selector: "cortex-json-tree", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, expandDepth: { classPropertyName: "expandDepth", publicName: "expandDepth", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "cortex-json-tree" }, ngImport: i0, template: "<!-- 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)\">▾</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)\">▾</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", styles: [".cortex-json-tree{display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;line-height:1.25rem;-webkit-user-select:text;user-select:text;white-space:pre-wrap;word-break:break-word}.jt-indent{padding-inline-start:1.25em;border-inline-start:1px solid #e2e8f0;margin-inline-start:.3em}.jt-line{position:relative}.jt-toggle{cursor:pointer;-webkit-user-select:none;user-select:none}.jt-toggle:hover .jt-arrow{color:#475569}.jt-arrow{display:inline-block;width:1em;text-align:center;color:#94a3b8;font-size:.7em;transition:transform .15s ease;vertical-align:middle}.jt-arrow--collapsed{transform:rotate(-90deg)}.jt-bracket{color:#64748b}.jt-key{color:#6366f1}.jt-colon{color:#64748b}.jt-comma{color:#94a3b8}.jt-string{color:#059669}.jt-number{color:#2563eb}.jt-boolean{color:#d97706}.jt-null{color:#94a3b8;font-style:italic}.jt-collapsed-hint{display:inline-block;padding:0 .4em;margin:0 .15em;font-size:10px;line-height:1.5;color:#94a3b8;background:#f8fafc;border:1px solid #e2e8f0;border-radius:3px;font-style:italic;cursor:pointer;-webkit-user-select:none;user-select:none;vertical-align:middle}.jt-collapsed-hint:hover{color:#64748b;border-color:#cbd5e1;background:#f1f5f9}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
608
835
|
}
|
|
609
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: JsonTreeComponent, decorators: [{
|
|
610
837
|
type: Component,
|
|
611
838
|
args: [{ selector: 'cortex-json-tree', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet], host: { class: 'cortex-json-tree' }, template: "<!-- 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)\">▾</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)\">▾</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", styles: [".cortex-json-tree{display:block;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;line-height:1.25rem;-webkit-user-select:text;user-select:text;white-space:pre-wrap;word-break:break-word}.jt-indent{padding-inline-start:1.25em;border-inline-start:1px solid #e2e8f0;margin-inline-start:.3em}.jt-line{position:relative}.jt-toggle{cursor:pointer;-webkit-user-select:none;user-select:none}.jt-toggle:hover .jt-arrow{color:#475569}.jt-arrow{display:inline-block;width:1em;text-align:center;color:#94a3b8;font-size:.7em;transition:transform .15s ease;vertical-align:middle}.jt-arrow--collapsed{transform:rotate(-90deg)}.jt-bracket{color:#64748b}.jt-key{color:#6366f1}.jt-colon{color:#64748b}.jt-comma{color:#94a3b8}.jt-string{color:#059669}.jt-number{color:#2563eb}.jt-boolean{color:#d97706}.jt-null{color:#94a3b8;font-style:italic}.jt-collapsed-hint{display:inline-block;padding:0 .4em;margin:0 .15em;font-size:10px;line-height:1.5;color:#94a3b8;background:#f8fafc;border:1px solid #e2e8f0;border-radius:3px;font-style:italic;cursor:pointer;-webkit-user-select:none;user-select:none;vertical-align:middle}.jt-collapsed-hint:hover{color:#64748b;border-color:#cbd5e1;background:#f1f5f9}\n"] }]
|
|
612
839
|
}], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], expandDepth: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandDepth", required: false }] }] } });
|
|
@@ -656,10 +883,10 @@ class MessageToolCallPartComponent {
|
|
|
656
883
|
return '';
|
|
657
884
|
return type.startsWith('tool-') ? type.slice('tool-'.length) : type;
|
|
658
885
|
}
|
|
659
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
660
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MessageToolCallPartComponent, isStandalone: true, selector: "cortex-message-tool-call-part", inputs: { toolCallPart: { classPropertyName: "toolCallPart", publicName: "toolCallPart", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<details class=\"cortex-tool-details\">\n <summary class=\"cortex-tool-details__summary\">\n <div class=\"cortex-tool-details__header\">\n <div class=\"cortex-tool-details__icon-box\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-tool-details__icon-svg\" 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=\"cortex-tool-details__info\">\n <div class=\"cortex-tool-details__title-row\">\n <div class=\"cortex-tool-details__name-row\">\n <div class=\"cortex-tool-details__name\" [attr.title]=\"toolCallPart().title || null\">\n {{ toolCallPart().title ?? 'Tool call' }}\n </div>\n @if (toolName()) {\n <span\n class=\"cortex-tool-details__tool-badge\"\n [attr.title]=\"toolCallPart().type || null\"\n >{{ toolName() }}</span\n >\n }\n </div>\n <div class=\"cortex-tool-details__id-line\">\n <span class=\"cortex-tool-details__id-label\">ID</span>\n <span class=\"cortex-tool-details__id-value\"> {{ toolCallPart().toolCallId }}</span>\n @if (toolCallPart().providerExecuted) {\n <span class=\"cortex-tool-details__provider-badge\">\n <span class=\"cortex-tool-details__provider-dot\"></span>\n provider\n </span>\n }\n </div>\n </div>\n\n <div class=\"cortex-tool-details__actions\">\n <span\n class=\"cortex-tool-details__state-badge\"\n [ngClass]=\"{\n 'cortex-tool-details__state-badge--success':\n toolCallPart().state === 'output-available',\n 'cortex-tool-details__state-badge--error': toolCallPart().state === 'output-error',\n 'cortex-tool-details__state-badge--denied': toolCallPart().state === 'output-denied',\n 'cortex-tool-details__state-badge--approval':\n toolCallPart().state === 'approval-requested' ||\n toolCallPart().state === 'approval-responded',\n 'cortex-tool-details__state-badge--pending':\n toolCallPart().state === 'input-streaming' ||\n toolCallPart().state === 'input-available',\n }\"\n >\n @switch (toolCallPart().state) {\n @case ('input-streaming') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--amber cortex-tool-details__status-dot--pulse\"\n ></span>\n Calling\n }\n @case ('input-available') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--amber\"\n ></span>\n Input ready\n }\n @case ('approval-requested') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--violet cortex-tool-details__status-dot--pulse\"\n ></span>\n Needs approval\n }\n @case ('approval-responded') {\n @if (toolCallPart().approval?.approved) {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--emerald\"\n ></span>\n Approved\n } @else {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--slate\"\n ></span>\n Responded\n }\n }\n @case ('output-available') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--emerald\"\n ></span>\n {{ 'translate_completed' | translate }}\n }\n @case ('output-error') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--red\"\n ></span>\n Error\n }\n @case ('output-denied') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--slate\"\n ></span>\n Denied\n }\n }\n </span>\n\n <span class=\"cortex-tool-details__chevron\" aria-hidden=\"true\">\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 </summary>\n\n <div class=\"cortex-tool-details__body\">\n <div class=\"cortex-tool-details__panels\">\n @for (snippet of codeSnippets(); track snippet.key) {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">{{ snippet.key }}</div>\n <div class=\"cortex-tool-details__panel-lang\">{{ snippet.lang }}</div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"cortex-tool-details__code-pre\"\n ><code class=\"hljs\" [innerHTML]=\"snippet.value | highlight : snippet.lang\"></code></pre>\n </div>\n }\n\n @if (remainingInput(); as remaining) {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">Input</div>\n <div class=\"cortex-tool-details__panel-lang\">json</div>\n </div>\n <div dir=\"ltr\" class=\"cortex-tool-details__tree-container\">\n <cortex-json-tree [data]=\"remaining\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-available') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--success\">\n <div class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--success\">\n <div class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--success\">\n Output\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--success\">\n json\n </div>\n </div>\n <div dir=\"ltr\" class=\"cortex-tool-details__tree-container\">\n <cortex-json-tree [data]=\"toolCallPart().output\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-error') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--error\">\n <div class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--error\">\n <div class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--error\">\n Error\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--error\">\n text\n </div>\n </div>\n <pre dir=\"ltr\" class=\"cortex-tool-details__error-pre\">{{ toolCallPart().errorText }}</pre>\n </div>\n }\n\n @if (toolCallPart().state === 'output-denied') {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">Denied</div>\n <div class=\"cortex-tool-details__panel-lang\">approval</div>\n </div>\n <div class=\"cortex-tool-details__denied-body\">\n Tool execution was denied.\n @if (toolCallPart().approval?.reason) {\n <div class=\"cortex-tool-details__reason-box\">\n <div class=\"cortex-tool-details__reason-label\">Reason</div>\n <div class=\"cortex-tool-details__reason-text\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-requested') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--approval\">\n <div\n class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--approval\"\n >\n <div\n class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--approval\"\n >\n Approval requested\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--approval\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"cortex-tool-details__approval-body\">\n Waiting for approval to execute this tool.\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-responded') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--approval\">\n <div\n class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--approval\"\n >\n <div\n class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--approval\"\n >\n Approval response\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--approval\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"cortex-tool-details__approval-body\">\n @if (toolCallPart().approval?.approved) {\n Approved.\n } @else {\n Response received.\n }\n @if (toolCallPart().approval?.reason) {\n <div\n class=\"cortex-tool-details__reason-box cortex-tool-details__reason-box--approval\"\n >\n <div\n class=\"cortex-tool-details__reason-label cortex-tool-details__reason-label--approval\"\n >\n Reason\n </div>\n <div\n class=\"cortex-tool-details__reason-text cortex-tool-details__reason-text--approval\"\n >\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</details>\n", styles: [".cortex-tool-details{width:100%;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cortex-tool-details__summary{list-style:none;cursor:pointer;-webkit-user-select:none;user-select:none;padding:.75rem 1rem}.cortex-tool-details__summary::-webkit-details-marker{display:none}details[open]>.cortex-tool-details__summary{border-bottom:1px solid #e2e8f0}.cortex-tool-details__header{display:flex;align-items:flex-start;gap:.75rem}.cortex-tool-details__icon-box{flex-shrink:0;margin-top:.125rem;width:1.75rem;height:1.75rem;border-radius:.25rem;background:#1e293b;color:#fff;display:flex;align-items:center;justify-content:center}.cortex-tool-details__icon-svg{width:1rem;height:1rem}.cortex-tool-details__info{min-width:0;flex:1;display:flex;align-items:center;gap:.5rem}.cortex-tool-details__title-row{min-width:0;flex:1}.cortex-tool-details__name-row{display:flex;align-items:center;gap:.5rem;min-width:0}.cortex-tool-details__name{font-weight:500;color:#1e293b;font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cortex-tool-details__tool-badge{display:none;align-items:center;border-radius:.25rem;background:#e2e8f0;padding:.125rem .375rem;font-size:.6875rem;font-weight:500;color:#475569;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}@media(min-width:640px){.cortex-tool-details__tool-badge{display:inline-flex}}.cortex-tool-details__id-line{margin-top:.125rem;font-size:.6875rem;color:#64748b;word-break:break-all}.cortex-tool-details__id-label{font-weight:500;color:#475569}.cortex-tool-details__id-value{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.cortex-tool-details__provider-badge{margin-inline-start:.5rem;display:inline-flex;align-items:center;gap:.25rem;color:#047857}.cortex-tool-details__provider-dot{width:.375rem;height:.375rem;border-radius:9999px;background:#10b981}.cortex-tool-details__actions{display:flex;align-items:center;gap:.5rem}.cortex-tool-details__state-badge{display:inline-flex;align-items:center;gap:.375rem;border-radius:.25rem;padding:.25rem .5rem;font-size:.6875rem;font-weight:500;border:1px solid}.cortex-tool-details__state-badge--success{background:#ecfdf5;color:#047857;border-color:#a7f3d0}.cortex-tool-details__state-badge--error{background:#fef2f2;color:#b91c1c;border-color:#fecaca}.cortex-tool-details__state-badge--denied{background:#f1f5f9;color:#475569;border-color:#e2e8f0}.cortex-tool-details__state-badge--approval{background:#f5f3ff;color:#6d28d9;border-color:#ddd6fe}.cortex-tool-details__state-badge--pending{background:#fffbeb;color:#b45309;border-color:#fde68a}.cortex-tool-details__status-dot{width:.375rem;height:.375rem;border-radius:9999px}.cortex-tool-details__status-dot--amber{background:#f59e0b}.cortex-tool-details__status-dot--violet{background:#8b5cf6}.cortex-tool-details__status-dot--emerald{background:#10b981}.cortex-tool-details__status-dot--red{background:#ef4444}.cortex-tool-details__status-dot--slate{background:#64748b}.cortex-tool-details__status-dot--pulse{animation:cortex-tool-status-pulse 2s ease-in-out infinite}@keyframes cortex-tool-status-pulse{0%,to{opacity:1}50%{opacity:.4}}.cortex-tool-details__chevron{display:inline-flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;color:#94a3b8;transition:transform .2s}details[open]>summary .cortex-tool-details__chevron{transform:rotate(180deg)}.cortex-tool-details__body{background:#fff;padding:.75rem 1rem 1rem}.cortex-tool-details__panels{display:grid;gap:.75rem}.cortex-tool-details__panel{border-radius:.5rem;border:1px solid #e2e8f0;overflow:hidden}.cortex-tool-details__panel--success{border-color:#a7f3d0}.cortex-tool-details__panel--error{border-color:#fecaca}.cortex-tool-details__panel--approval{border-color:#ddd6fe}.cortex-tool-details__panel-header{padding:.5rem .75rem;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #e2e8f0;background:#f8fafc}.cortex-tool-details__panel-header--success{border-bottom-color:#a7f3d0;background:#ecfdf5}.cortex-tool-details__panel-header--error{border-bottom-color:#fecaca;background:#fef2f2}.cortex-tool-details__panel-header--approval{border-bottom-color:#ddd6fe;background:#f5f3ff}.cortex-tool-details__panel-label{font-size:.6875rem;font-weight:500;color:#475569}.cortex-tool-details__panel-label--success{color:#047857}.cortex-tool-details__panel-label--error{color:#b91c1c}.cortex-tool-details__panel-label--approval{color:#6d28d9}.cortex-tool-details__panel-lang{font-size:.6875rem;color:#94a3b8;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.cortex-tool-details__panel-lang--success{color:#059669}.cortex-tool-details__panel-lang--error{color:#dc2626}.cortex-tool-details__panel-lang--approval{color:#7c3aed}.cortex-tool-details__code-pre{margin:0;max-height:20rem;overflow:auto;padding:.75rem;font-size:.75rem;line-height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre;overflow-wrap:break-word}.cortex-tool-details__tree-container{max-height:16rem;overflow:auto;padding:.75rem}.cortex-tool-details__error-pre{margin:0;max-height:16rem;overflow:auto;padding:.75rem;font-size:.75rem;line-height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;color:#991b1b;white-space:pre-wrap;overflow-wrap:break-word}.cortex-tool-details__denied-body{padding:.75rem;font-size:.75rem;color:#334155}.cortex-tool-details__approval-body{padding:.75rem;font-size:.75rem;color:#5b21b6}.cortex-tool-details__reason-box{margin-top:.5rem;border-radius:.25rem;background:#f8fafc;border:1px solid #e2e8f0;padding:.5rem}.cortex-tool-details__reason-box--approval{background:#f5f3ff;border-color:#ddd6fe}.cortex-tool-details__reason-label{font-size:.6875rem;font-weight:500;color:#475569}.cortex-tool-details__reason-label--approval{color:#6d28d9}.cortex-tool-details__reason-text{margin-top:.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;color:#334155;overflow-wrap:break-word}.cortex-tool-details__reason-text--approval{color:#5b21b6}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: JsonTreeComponent, selector: "cortex-json-tree", inputs: ["data", "expandDepth"] }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
886
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageToolCallPartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
887
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageToolCallPartComponent, isStandalone: true, selector: "cortex-message-tool-call-part", inputs: { toolCallPart: { classPropertyName: "toolCallPart", publicName: "toolCallPart", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<details class=\"cortex-tool-details\">\n <summary class=\"cortex-tool-details__summary\">\n <div class=\"cortex-tool-details__header\">\n <div class=\"cortex-tool-details__icon-box\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-tool-details__icon-svg\" 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=\"cortex-tool-details__info\">\n <div class=\"cortex-tool-details__title-row\">\n <div class=\"cortex-tool-details__name-row\">\n <div class=\"cortex-tool-details__name\" [attr.title]=\"toolCallPart().title || null\">\n {{ toolCallPart().title ?? 'Tool call' }}\n </div>\n @if (toolName()) {\n <span\n class=\"cortex-tool-details__tool-badge\"\n [attr.title]=\"toolCallPart().type || null\"\n >{{ toolName() }}</span\n >\n }\n </div>\n <div class=\"cortex-tool-details__id-line\">\n <span class=\"cortex-tool-details__id-label\">ID</span>\n <span class=\"cortex-tool-details__id-value\"> {{ toolCallPart().toolCallId }}</span>\n @if (toolCallPart().providerExecuted) {\n <span class=\"cortex-tool-details__provider-badge\">\n <span class=\"cortex-tool-details__provider-dot\"></span>\n provider\n </span>\n }\n </div>\n </div>\n\n <div class=\"cortex-tool-details__actions\">\n <span\n class=\"cortex-tool-details__state-badge\"\n [ngClass]=\"{\n 'cortex-tool-details__state-badge--success':\n toolCallPart().state === 'output-available',\n 'cortex-tool-details__state-badge--error': toolCallPart().state === 'output-error',\n 'cortex-tool-details__state-badge--denied': toolCallPart().state === 'output-denied',\n 'cortex-tool-details__state-badge--approval':\n toolCallPart().state === 'approval-requested' ||\n toolCallPart().state === 'approval-responded',\n 'cortex-tool-details__state-badge--pending':\n toolCallPart().state === 'input-streaming' ||\n toolCallPart().state === 'input-available',\n }\"\n >\n @switch (toolCallPart().state) {\n @case ('input-streaming') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--amber cortex-tool-details__status-dot--pulse\"\n ></span>\n Calling\n }\n @case ('input-available') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--amber\"\n ></span>\n Input ready\n }\n @case ('approval-requested') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--violet cortex-tool-details__status-dot--pulse\"\n ></span>\n Needs approval\n }\n @case ('approval-responded') {\n @if (toolCallPart().approval?.approved) {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--emerald\"\n ></span>\n Approved\n } @else {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--slate\"\n ></span>\n Responded\n }\n }\n @case ('output-available') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--emerald\"\n ></span>\n {{ 'translate_completed' | translate }}\n }\n @case ('output-error') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--red\"\n ></span>\n Error\n }\n @case ('output-denied') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--slate\"\n ></span>\n Denied\n }\n }\n </span>\n\n <span class=\"cortex-tool-details__chevron\" aria-hidden=\"true\">\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 </summary>\n\n <div class=\"cortex-tool-details__body\">\n <div class=\"cortex-tool-details__panels\">\n @for (snippet of codeSnippets(); track snippet.key) {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">{{ snippet.key }}</div>\n <div class=\"cortex-tool-details__panel-lang\">{{ snippet.lang }}</div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"cortex-tool-details__code-pre\"\n ><code class=\"hljs\" [innerHTML]=\"snippet.value | highlight : snippet.lang\"></code></pre>\n </div>\n }\n\n @if (remainingInput(); as remaining) {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">Input</div>\n <div class=\"cortex-tool-details__panel-lang\">json</div>\n </div>\n <div dir=\"ltr\" class=\"cortex-tool-details__tree-container\">\n <cortex-json-tree [data]=\"remaining\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-available') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--success\">\n <div class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--success\">\n <div class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--success\">\n Output\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--success\">\n json\n </div>\n </div>\n <div dir=\"ltr\" class=\"cortex-tool-details__tree-container\">\n <cortex-json-tree [data]=\"toolCallPart().output\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-error') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--error\">\n <div class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--error\">\n <div class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--error\">\n Error\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--error\">\n text\n </div>\n </div>\n <pre dir=\"ltr\" class=\"cortex-tool-details__error-pre\">{{ toolCallPart().errorText }}</pre>\n </div>\n }\n\n @if (toolCallPart().state === 'output-denied') {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">Denied</div>\n <div class=\"cortex-tool-details__panel-lang\">approval</div>\n </div>\n <div class=\"cortex-tool-details__denied-body\">\n Tool execution was denied.\n @if (toolCallPart().approval?.reason) {\n <div class=\"cortex-tool-details__reason-box\">\n <div class=\"cortex-tool-details__reason-label\">Reason</div>\n <div class=\"cortex-tool-details__reason-text\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-requested') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--approval\">\n <div\n class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--approval\"\n >\n <div\n class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--approval\"\n >\n Approval requested\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--approval\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"cortex-tool-details__approval-body\">\n Waiting for approval to execute this tool.\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-responded') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--approval\">\n <div\n class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--approval\"\n >\n <div\n class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--approval\"\n >\n Approval response\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--approval\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"cortex-tool-details__approval-body\">\n @if (toolCallPart().approval?.approved) {\n Approved.\n } @else {\n Response received.\n }\n @if (toolCallPart().approval?.reason) {\n <div\n class=\"cortex-tool-details__reason-box cortex-tool-details__reason-box--approval\"\n >\n <div\n class=\"cortex-tool-details__reason-label cortex-tool-details__reason-label--approval\"\n >\n Reason\n </div>\n <div\n class=\"cortex-tool-details__reason-text cortex-tool-details__reason-text--approval\"\n >\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</details>\n", styles: [".cortex-tool-details{width:100%;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cortex-tool-details__summary{list-style:none;cursor:pointer;-webkit-user-select:none;user-select:none;padding:.75rem 1rem}.cortex-tool-details__summary::-webkit-details-marker{display:none}details[open]>.cortex-tool-details__summary{border-bottom:1px solid #e2e8f0}.cortex-tool-details__header{display:flex;align-items:flex-start;gap:.75rem}.cortex-tool-details__icon-box{flex-shrink:0;margin-top:.125rem;width:1.75rem;height:1.75rem;border-radius:.25rem;background:#1e293b;color:#fff;display:flex;align-items:center;justify-content:center}.cortex-tool-details__icon-svg{width:1rem;height:1rem}.cortex-tool-details__info{min-width:0;flex:1;display:flex;align-items:center;gap:.5rem}.cortex-tool-details__title-row{min-width:0;flex:1}.cortex-tool-details__name-row{display:flex;align-items:center;gap:.5rem;min-width:0}.cortex-tool-details__name{font-weight:500;color:#1e293b;font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cortex-tool-details__tool-badge{display:none;align-items:center;border-radius:.25rem;background:#e2e8f0;padding:.125rem .375rem;font-size:.6875rem;font-weight:500;color:#475569;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}@media(min-width:640px){.cortex-tool-details__tool-badge{display:inline-flex}}.cortex-tool-details__id-line{margin-top:.125rem;font-size:.6875rem;color:#64748b;word-break:break-all}.cortex-tool-details__id-label{font-weight:500;color:#475569}.cortex-tool-details__id-value{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.cortex-tool-details__provider-badge{margin-inline-start:.5rem;display:inline-flex;align-items:center;gap:.25rem;color:#047857}.cortex-tool-details__provider-dot{width:.375rem;height:.375rem;border-radius:9999px;background:#10b981}.cortex-tool-details__actions{display:flex;align-items:center;gap:.5rem}.cortex-tool-details__state-badge{display:inline-flex;align-items:center;gap:.375rem;border-radius:.25rem;padding:.25rem .5rem;font-size:.6875rem;font-weight:500;border:1px solid}.cortex-tool-details__state-badge--success{background:#ecfdf5;color:#047857;border-color:#a7f3d0}.cortex-tool-details__state-badge--error{background:#fef2f2;color:#b91c1c;border-color:#fecaca}.cortex-tool-details__state-badge--denied{background:#f1f5f9;color:#475569;border-color:#e2e8f0}.cortex-tool-details__state-badge--approval{background:#f5f3ff;color:#6d28d9;border-color:#ddd6fe}.cortex-tool-details__state-badge--pending{background:#fffbeb;color:#b45309;border-color:#fde68a}.cortex-tool-details__status-dot{width:.375rem;height:.375rem;border-radius:9999px}.cortex-tool-details__status-dot--amber{background:#f59e0b}.cortex-tool-details__status-dot--violet{background:#8b5cf6}.cortex-tool-details__status-dot--emerald{background:#10b981}.cortex-tool-details__status-dot--red{background:#ef4444}.cortex-tool-details__status-dot--slate{background:#64748b}.cortex-tool-details__status-dot--pulse{animation:cortex-tool-status-pulse 2s ease-in-out infinite}@keyframes cortex-tool-status-pulse{0%,to{opacity:1}50%{opacity:.4}}.cortex-tool-details__chevron{display:inline-flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;color:#94a3b8;transition:transform .2s}details[open]>summary .cortex-tool-details__chevron{transform:rotate(180deg)}.cortex-tool-details__body{background:#fff;padding:.75rem 1rem 1rem}.cortex-tool-details__panels{display:grid;gap:.75rem}.cortex-tool-details__panel{border-radius:.5rem;border:1px solid #e2e8f0;overflow:hidden}.cortex-tool-details__panel--success{border-color:#a7f3d0}.cortex-tool-details__panel--error{border-color:#fecaca}.cortex-tool-details__panel--approval{border-color:#ddd6fe}.cortex-tool-details__panel-header{padding:.5rem .75rem;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #e2e8f0;background:#f8fafc}.cortex-tool-details__panel-header--success{border-bottom-color:#a7f3d0;background:#ecfdf5}.cortex-tool-details__panel-header--error{border-bottom-color:#fecaca;background:#fef2f2}.cortex-tool-details__panel-header--approval{border-bottom-color:#ddd6fe;background:#f5f3ff}.cortex-tool-details__panel-label{font-size:.6875rem;font-weight:500;color:#475569}.cortex-tool-details__panel-label--success{color:#047857}.cortex-tool-details__panel-label--error{color:#b91c1c}.cortex-tool-details__panel-label--approval{color:#6d28d9}.cortex-tool-details__panel-lang{font-size:.6875rem;color:#94a3b8;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.cortex-tool-details__panel-lang--success{color:#059669}.cortex-tool-details__panel-lang--error{color:#dc2626}.cortex-tool-details__panel-lang--approval{color:#7c3aed}.cortex-tool-details__code-pre{margin:0;max-height:20rem;overflow:auto;padding:.75rem;font-size:.75rem;line-height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre;overflow-wrap:break-word}.cortex-tool-details__tree-container{max-height:16rem;overflow:auto;padding:.75rem}.cortex-tool-details__error-pre{margin:0;max-height:16rem;overflow:auto;padding:.75rem;font-size:.75rem;line-height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;color:#991b1b;white-space:pre-wrap;overflow-wrap:break-word}.cortex-tool-details__denied-body{padding:.75rem;font-size:.75rem;color:#334155}.cortex-tool-details__approval-body{padding:.75rem;font-size:.75rem;color:#5b21b6}.cortex-tool-details__reason-box{margin-top:.5rem;border-radius:.25rem;background:#f8fafc;border:1px solid #e2e8f0;padding:.5rem}.cortex-tool-details__reason-box--approval{background:#f5f3ff;border-color:#ddd6fe}.cortex-tool-details__reason-label{font-size:.6875rem;font-weight:500;color:#475569}.cortex-tool-details__reason-label--approval{color:#6d28d9}.cortex-tool-details__reason-text{margin-top:.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;color:#334155;overflow-wrap:break-word}.cortex-tool-details__reason-text--approval{color:#5b21b6}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: JsonTreeComponent, selector: "cortex-json-tree", inputs: ["data", "expandDepth"] }, { kind: "pipe", type: HighlightPipe, name: "highlight" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
661
888
|
}
|
|
662
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
889
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageToolCallPartComponent, decorators: [{
|
|
663
890
|
type: Component,
|
|
664
891
|
args: [{ selector: 'cortex-message-tool-call-part', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [HighlightPipe, NgClass, TranslatePipe, JsonTreeComponent], template: "<details class=\"cortex-tool-details\">\n <summary class=\"cortex-tool-details__summary\">\n <div class=\"cortex-tool-details__header\">\n <div class=\"cortex-tool-details__icon-box\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-tool-details__icon-svg\" 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=\"cortex-tool-details__info\">\n <div class=\"cortex-tool-details__title-row\">\n <div class=\"cortex-tool-details__name-row\">\n <div class=\"cortex-tool-details__name\" [attr.title]=\"toolCallPart().title || null\">\n {{ toolCallPart().title ?? 'Tool call' }}\n </div>\n @if (toolName()) {\n <span\n class=\"cortex-tool-details__tool-badge\"\n [attr.title]=\"toolCallPart().type || null\"\n >{{ toolName() }}</span\n >\n }\n </div>\n <div class=\"cortex-tool-details__id-line\">\n <span class=\"cortex-tool-details__id-label\">ID</span>\n <span class=\"cortex-tool-details__id-value\"> {{ toolCallPart().toolCallId }}</span>\n @if (toolCallPart().providerExecuted) {\n <span class=\"cortex-tool-details__provider-badge\">\n <span class=\"cortex-tool-details__provider-dot\"></span>\n provider\n </span>\n }\n </div>\n </div>\n\n <div class=\"cortex-tool-details__actions\">\n <span\n class=\"cortex-tool-details__state-badge\"\n [ngClass]=\"{\n 'cortex-tool-details__state-badge--success':\n toolCallPart().state === 'output-available',\n 'cortex-tool-details__state-badge--error': toolCallPart().state === 'output-error',\n 'cortex-tool-details__state-badge--denied': toolCallPart().state === 'output-denied',\n 'cortex-tool-details__state-badge--approval':\n toolCallPart().state === 'approval-requested' ||\n toolCallPart().state === 'approval-responded',\n 'cortex-tool-details__state-badge--pending':\n toolCallPart().state === 'input-streaming' ||\n toolCallPart().state === 'input-available',\n }\"\n >\n @switch (toolCallPart().state) {\n @case ('input-streaming') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--amber cortex-tool-details__status-dot--pulse\"\n ></span>\n Calling\n }\n @case ('input-available') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--amber\"\n ></span>\n Input ready\n }\n @case ('approval-requested') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--violet cortex-tool-details__status-dot--pulse\"\n ></span>\n Needs approval\n }\n @case ('approval-responded') {\n @if (toolCallPart().approval?.approved) {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--emerald\"\n ></span>\n Approved\n } @else {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--slate\"\n ></span>\n Responded\n }\n }\n @case ('output-available') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--emerald\"\n ></span>\n {{ 'translate_completed' | translate }}\n }\n @case ('output-error') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--red\"\n ></span>\n Error\n }\n @case ('output-denied') {\n <span\n class=\"cortex-tool-details__status-dot cortex-tool-details__status-dot--slate\"\n ></span>\n Denied\n }\n }\n </span>\n\n <span class=\"cortex-tool-details__chevron\" aria-hidden=\"true\">\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 </summary>\n\n <div class=\"cortex-tool-details__body\">\n <div class=\"cortex-tool-details__panels\">\n @for (snippet of codeSnippets(); track snippet.key) {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">{{ snippet.key }}</div>\n <div class=\"cortex-tool-details__panel-lang\">{{ snippet.lang }}</div>\n </div>\n <pre\n dir=\"ltr\"\n class=\"cortex-tool-details__code-pre\"\n ><code class=\"hljs\" [innerHTML]=\"snippet.value | highlight : snippet.lang\"></code></pre>\n </div>\n }\n\n @if (remainingInput(); as remaining) {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">Input</div>\n <div class=\"cortex-tool-details__panel-lang\">json</div>\n </div>\n <div dir=\"ltr\" class=\"cortex-tool-details__tree-container\">\n <cortex-json-tree [data]=\"remaining\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-available') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--success\">\n <div class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--success\">\n <div class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--success\">\n Output\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--success\">\n json\n </div>\n </div>\n <div dir=\"ltr\" class=\"cortex-tool-details__tree-container\">\n <cortex-json-tree [data]=\"toolCallPart().output\" [expandDepth]=\"2\" />\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'output-error') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--error\">\n <div class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--error\">\n <div class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--error\">\n Error\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--error\">\n text\n </div>\n </div>\n <pre dir=\"ltr\" class=\"cortex-tool-details__error-pre\">{{ toolCallPart().errorText }}</pre>\n </div>\n }\n\n @if (toolCallPart().state === 'output-denied') {\n <div class=\"cortex-tool-details__panel\">\n <div class=\"cortex-tool-details__panel-header\">\n <div class=\"cortex-tool-details__panel-label\">Denied</div>\n <div class=\"cortex-tool-details__panel-lang\">approval</div>\n </div>\n <div class=\"cortex-tool-details__denied-body\">\n Tool execution was denied.\n @if (toolCallPart().approval?.reason) {\n <div class=\"cortex-tool-details__reason-box\">\n <div class=\"cortex-tool-details__reason-label\">Reason</div>\n <div class=\"cortex-tool-details__reason-text\">\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-requested') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--approval\">\n <div\n class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--approval\"\n >\n <div\n class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--approval\"\n >\n Approval requested\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--approval\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"cortex-tool-details__approval-body\">\n Waiting for approval to execute this tool.\n </div>\n </div>\n }\n\n @if (toolCallPart().state === 'approval-responded') {\n <div class=\"cortex-tool-details__panel cortex-tool-details__panel--approval\">\n <div\n class=\"cortex-tool-details__panel-header cortex-tool-details__panel-header--approval\"\n >\n <div\n class=\"cortex-tool-details__panel-label cortex-tool-details__panel-label--approval\"\n >\n Approval response\n </div>\n <div class=\"cortex-tool-details__panel-lang cortex-tool-details__panel-lang--approval\">\n {{ toolCallPart().approval?.id }}\n </div>\n </div>\n <div class=\"cortex-tool-details__approval-body\">\n @if (toolCallPart().approval?.approved) {\n Approved.\n } @else {\n Response received.\n }\n @if (toolCallPart().approval?.reason) {\n <div\n class=\"cortex-tool-details__reason-box cortex-tool-details__reason-box--approval\"\n >\n <div\n class=\"cortex-tool-details__reason-label cortex-tool-details__reason-label--approval\"\n >\n Reason\n </div>\n <div\n class=\"cortex-tool-details__reason-text cortex-tool-details__reason-text--approval\"\n >\n {{ toolCallPart().approval?.reason }}\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</details>\n", styles: [".cortex-tool-details{width:100%;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;overflow:hidden}.cortex-tool-details__summary{list-style:none;cursor:pointer;-webkit-user-select:none;user-select:none;padding:.75rem 1rem}.cortex-tool-details__summary::-webkit-details-marker{display:none}details[open]>.cortex-tool-details__summary{border-bottom:1px solid #e2e8f0}.cortex-tool-details__header{display:flex;align-items:flex-start;gap:.75rem}.cortex-tool-details__icon-box{flex-shrink:0;margin-top:.125rem;width:1.75rem;height:1.75rem;border-radius:.25rem;background:#1e293b;color:#fff;display:flex;align-items:center;justify-content:center}.cortex-tool-details__icon-svg{width:1rem;height:1rem}.cortex-tool-details__info{min-width:0;flex:1;display:flex;align-items:center;gap:.5rem}.cortex-tool-details__title-row{min-width:0;flex:1}.cortex-tool-details__name-row{display:flex;align-items:center;gap:.5rem;min-width:0}.cortex-tool-details__name{font-weight:500;color:#1e293b;font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cortex-tool-details__tool-badge{display:none;align-items:center;border-radius:.25rem;background:#e2e8f0;padding:.125rem .375rem;font-size:.6875rem;font-weight:500;color:#475569;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}@media(min-width:640px){.cortex-tool-details__tool-badge{display:inline-flex}}.cortex-tool-details__id-line{margin-top:.125rem;font-size:.6875rem;color:#64748b;word-break:break-all}.cortex-tool-details__id-label{font-weight:500;color:#475569}.cortex-tool-details__id-value{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.cortex-tool-details__provider-badge{margin-inline-start:.5rem;display:inline-flex;align-items:center;gap:.25rem;color:#047857}.cortex-tool-details__provider-dot{width:.375rem;height:.375rem;border-radius:9999px;background:#10b981}.cortex-tool-details__actions{display:flex;align-items:center;gap:.5rem}.cortex-tool-details__state-badge{display:inline-flex;align-items:center;gap:.375rem;border-radius:.25rem;padding:.25rem .5rem;font-size:.6875rem;font-weight:500;border:1px solid}.cortex-tool-details__state-badge--success{background:#ecfdf5;color:#047857;border-color:#a7f3d0}.cortex-tool-details__state-badge--error{background:#fef2f2;color:#b91c1c;border-color:#fecaca}.cortex-tool-details__state-badge--denied{background:#f1f5f9;color:#475569;border-color:#e2e8f0}.cortex-tool-details__state-badge--approval{background:#f5f3ff;color:#6d28d9;border-color:#ddd6fe}.cortex-tool-details__state-badge--pending{background:#fffbeb;color:#b45309;border-color:#fde68a}.cortex-tool-details__status-dot{width:.375rem;height:.375rem;border-radius:9999px}.cortex-tool-details__status-dot--amber{background:#f59e0b}.cortex-tool-details__status-dot--violet{background:#8b5cf6}.cortex-tool-details__status-dot--emerald{background:#10b981}.cortex-tool-details__status-dot--red{background:#ef4444}.cortex-tool-details__status-dot--slate{background:#64748b}.cortex-tool-details__status-dot--pulse{animation:cortex-tool-status-pulse 2s ease-in-out infinite}@keyframes cortex-tool-status-pulse{0%,to{opacity:1}50%{opacity:.4}}.cortex-tool-details__chevron{display:inline-flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;border-radius:.25rem;color:#94a3b8;transition:transform .2s}details[open]>summary .cortex-tool-details__chevron{transform:rotate(180deg)}.cortex-tool-details__body{background:#fff;padding:.75rem 1rem 1rem}.cortex-tool-details__panels{display:grid;gap:.75rem}.cortex-tool-details__panel{border-radius:.5rem;border:1px solid #e2e8f0;overflow:hidden}.cortex-tool-details__panel--success{border-color:#a7f3d0}.cortex-tool-details__panel--error{border-color:#fecaca}.cortex-tool-details__panel--approval{border-color:#ddd6fe}.cortex-tool-details__panel-header{padding:.5rem .75rem;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #e2e8f0;background:#f8fafc}.cortex-tool-details__panel-header--success{border-bottom-color:#a7f3d0;background:#ecfdf5}.cortex-tool-details__panel-header--error{border-bottom-color:#fecaca;background:#fef2f2}.cortex-tool-details__panel-header--approval{border-bottom-color:#ddd6fe;background:#f5f3ff}.cortex-tool-details__panel-label{font-size:.6875rem;font-weight:500;color:#475569}.cortex-tool-details__panel-label--success{color:#047857}.cortex-tool-details__panel-label--error{color:#b91c1c}.cortex-tool-details__panel-label--approval{color:#6d28d9}.cortex-tool-details__panel-lang{font-size:.6875rem;color:#94a3b8;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace}.cortex-tool-details__panel-lang--success{color:#059669}.cortex-tool-details__panel-lang--error{color:#dc2626}.cortex-tool-details__panel-lang--approval{color:#7c3aed}.cortex-tool-details__code-pre{margin:0;max-height:20rem;overflow:auto;padding:.75rem;font-size:.75rem;line-height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre;overflow-wrap:break-word}.cortex-tool-details__tree-container{max-height:16rem;overflow:auto;padding:.75rem}.cortex-tool-details__error-pre{margin:0;max-height:16rem;overflow:auto;padding:.75rem;font-size:.75rem;line-height:1.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;color:#991b1b;white-space:pre-wrap;overflow-wrap:break-word}.cortex-tool-details__denied-body{padding:.75rem;font-size:.75rem;color:#334155}.cortex-tool-details__approval-body{padding:.75rem;font-size:.75rem;color:#5b21b6}.cortex-tool-details__reason-box{margin-top:.5rem;border-radius:.25rem;background:#f8fafc;border:1px solid #e2e8f0;padding:.5rem}.cortex-tool-details__reason-box--approval{background:#f5f3ff;border-color:#ddd6fe}.cortex-tool-details__reason-label{font-size:.6875rem;font-weight:500;color:#475569}.cortex-tool-details__reason-label--approval{color:#6d28d9}.cortex-tool-details__reason-text{margin-top:.25rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:.75rem;color:#334155;overflow-wrap:break-word}.cortex-tool-details__reason-text--approval{color:#5b21b6}\n"] }]
|
|
665
892
|
}], propDecorators: { toolCallPart: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolCallPart", required: true }] }] } });
|
|
@@ -751,10 +978,10 @@ class MessageCaptureFilesPartComponent {
|
|
|
751
978
|
message: 'User canceled upload',
|
|
752
979
|
});
|
|
753
980
|
}
|
|
754
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
755
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MessageCaptureFilesPartComponent, isStandalone: true, selector: "cortex-message-capture-files-part", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, toolPart: { classPropertyName: "toolPart", publicName: "toolPart", isSignal: true, isRequired: true, transformFunction: null }, setOutput: { classPropertyName: "setOutput", publicName: "setOutput", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "cortex-capture-files" }, ngImport: i0, template: "@if (outputData(); as output) {\n <!-- Result state -->\n @if (output.status === 'success') {\n <div class=\"cortex-capture-success\">\n <div class=\"cortex-capture-success__header\">\n <div class=\"cortex-capture-success__icon\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-success__icon-svg\" 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=\"cortex-capture-success__title-wrap\">\n <h3 class=\"cortex-capture-success__title\">\n {{ 'translate_files_attached' | translate: { count: requestedFiles().length } }}\n </h3>\n </div>\n </div>\n\n <div class=\"cortex-capture-success__file-list\">\n <ul class=\"cortex-capture-success__files\">\n @for (file of outputData()!.result!; track file.uploadId) {\n <li>\n <button\n type=\"button\"\n (click)=\"downloadFile(file.uploadId)\"\n class=\"cortex-capture-success__download-btn\"\n >\n <svg viewBox=\"0 0 16 16\" class=\"cortex-capture-success__file-icon\" 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=\"cortex-capture-success__file-name\">{{\n requestedFiles()[$index]?.label ?? outputData()!.result![$index]?.id\n }}</span>\n <svg viewBox=\"0 0 16 16\" class=\"cortex-capture-success__dl-icon\" 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=\"cortex-capture-canceled-wrap\">\n <div class=\"cortex-capture-canceled\">\n <div class=\"cortex-capture-canceled__icon\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-canceled__icon-svg\" fill=\"none\">\n <path d=\"M6 10h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </div>\n <span class=\"cortex-capture-canceled__text\">{{\n 'translate_file_upload_skipped' | translate\n }}</span>\n </div>\n </div>\n }\n} @else {\n @if (!hasInvalidInput()) {\n <!-- Upload form -->\n <form [formGroup]=\"form()\" class=\"cortex-capture-form\">\n @if (requestedFiles().length === 1) {\n <!-- Single file: minimal inline -->\n <fieldset [formArray]=\"form().controls.files\">\n <div [formGroupName]=\"0\" class=\"cortex-capture-form__single\">\n <label for=\"capture-file-0\" class=\"cortex-capture-form__label\">\n {{ requestedFiles()[0]!.label }}\n </label>\n <input hidden formControlName=\"id\" />\n <div class=\"cortex-capture-form__row\">\n <cortex-file-input\n id=\"capture-file-0\"\n formControlName=\"file\"\n class=\"cortex-capture-form__input\"\n />\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"cortex-capture-form__cancel-link\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"cortex-capture-form__submit-btn\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"cortex-capture-form__spinner\" 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=\"cortex-capture-form__spinner-track\"\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 class=\"cortex-capture-form__multi\">\n <div class=\"cortex-capture-form__multi-header\">\n <div class=\"cortex-capture-form__multi-header-row\">\n <div class=\"cortex-capture-form__multi-icon\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-form__multi-icon-svg\" 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=\"cortex-capture-form__multi-title-wrap\">\n <h3 class=\"cortex-capture-form__multi-title\">\n {{ 'translate_attach_requested_files' | translate }}\n </h3>\n <p class=\"cortex-capture-form__multi-subtitle\">\n {{ 'translate_n_files_required' | translate: { count: requestedFiles().length } }}\n </p>\n </div>\n </div>\n </div>\n\n <fieldset [formArray]=\"form().controls.files\" class=\"cortex-capture-form__multi-fields\">\n @for (file of form().controls.files.value; track $index) {\n <div [formGroupName]=\"$index\" class=\"cortex-capture-form__multi-item\">\n <div class=\"cortex-capture-form__multi-item-header\">\n <label\n [for]=\"'capture-file-' + $index\"\n class=\"cortex-capture-form__multi-item-label\"\n >\n {{ requestedFiles()[$index]!.label }}\n </label>\n <span class=\"cortex-capture-form__required-badge\">\n {{ 'translate_required' | translate }}\n </span>\n </div>\n <input hidden formControlName=\"id\" />\n <cortex-file-input [id]=\"'capture-file-' + $index\" formControlName=\"file\" />\n </div>\n }\n </fieldset>\n\n <div class=\"cortex-capture-form__multi-footer\">\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"cortex-capture-form__cancel-btn\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"cortex-capture-form__submit-btn\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"cortex-capture-form__spinner\" 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=\"cortex-capture-form__spinner-track\"\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}\n", styles: [".cortex-capture-files{display:block;width:100%}.cortex-file-input{display:flex;width:100%;cursor:pointer;align-items:center;border-radius:.5rem;border:1px solid #cbd5e1;background:#f8fafc;transition:border-color .15s}.cortex-file-input:hover{border-color:#94a3b8}.cortex-file-input:focus-within{box-shadow:0 0 0 2px #cbd5e1}.cortex-file-input__btn{margin:.25rem;flex-shrink:0;cursor:pointer;border-radius:.375rem;border:0;background:#1e293b;padding:.375rem .75rem;font-size:.6875rem;font-weight:600;letter-spacing:.025em;color:#f1f5f9}.cortex-file-input__btn:hover{background:#334155}.cortex-file-input__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 .75rem;font-size:.75rem;color:#475569}.cortex-file-input__hidden{display:none}.cortex-capture-success{overflow:hidden;border-radius:1rem;border:1px solid #a7f3d0;background:linear-gradient(to bottom,#ecfdf5cc,#fff)}.cortex-capture-success__header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-success__header{padding:.75rem 1.25rem}}.cortex-capture-success__icon{display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #a7f3d0;background:#d1fae5;color:#059669}.cortex-capture-success__icon-svg{width:1rem;height:1rem}.cortex-capture-success__title-wrap{min-width:0}.cortex-capture-success__title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#065f46;margin:0}.cortex-capture-success__file-list{border-top:1px solid #d1fae5;padding:.625rem 1rem}@media(min-width:640px){.cortex-capture-success__file-list{padding:.625rem 1.25rem}}.cortex-capture-success__files{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;margin:0;padding:0}.cortex-capture-success__download-btn{display:inline-flex;cursor:pointer;align-items:center;gap:.375rem;border-radius:.5rem;border:1px solid #d1fae5;background:#fff;padding:.375rem .625rem;font-size:.75rem;font-weight:500;color:#047857;box-shadow:0 1px 2px #0000000d;transition:all .15s}.cortex-capture-success__download-btn:hover{border-color:#a7f3d0;background:#ecfdf5;box-shadow:0 1px 3px #0000001a}.cortex-capture-success__download-btn:active{transform:scale(.97)}.cortex-capture-success__file-icon{width:.875rem;height:.875rem;flex-shrink:0;color:#6ee7b7}.cortex-capture-success__file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.cortex-capture-success__dl-icon{width:.75rem;height:.75rem;flex-shrink:0;color:#86efac}.cortex-capture-canceled-wrap{display:flex;justify-content:center}.cortex-capture-canceled{display:inline-flex;align-items:center;gap:.625rem;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.625rem 1rem}.cortex-capture-canceled__icon{display:inline-flex;width:1.5rem;height:1.5rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#94a3b8}.cortex-capture-canceled__icon-svg{width:.75rem;height:.75rem}.cortex-capture-canceled__text{font-size:.8125rem;font-weight:500;color:#94a3b8}.cortex-capture-form{width:100%}.cortex-capture-form__single{border-radius:.75rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.75rem}.cortex-capture-form__label{display:block;margin-bottom:.375rem;font-size:.75rem;color:#64748b}.cortex-capture-form__row{display:flex;align-items:center;gap:.5rem}.cortex-capture-form__input{min-width:0;flex:1}.cortex-capture-form__cancel-link{flex-shrink:0;font-size:.75rem;font-weight:500;color:#94a3b8;background:none;border:0;cursor:pointer;transition:color .15s}.cortex-capture-form__cancel-link:hover{color:#475569}.cortex-capture-form__submit-btn{display:inline-flex;flex-shrink:0;align-items:center;border-radius:.375rem;background:#1e293b;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#f1f5f9;border:0;cursor:pointer;transition:background-color .15s}.cortex-capture-form__submit-btn:hover{background:#334155}.cortex-capture-form__submit-btn:active{background:#0f172a}.cortex-capture-form__submit-btn:disabled{cursor:not-allowed;background:#cbd5e1}.cortex-capture-form__spinner{width:.75rem;height:.75rem;margin-inline-end:.375rem;animation:cortex-capture-spin .8s linear infinite}.cortex-capture-form__spinner-track{opacity:.25}@keyframes cortex-capture-spin{to{transform:rotate(360deg)}}.cortex-capture-form__multi{overflow:hidden;border-radius:1rem;border:1px solid #e2e8f0;background:linear-gradient(to bottom,#fff,#f8fafc)}.cortex-capture-form__multi-header{border-bottom:1px solid #e2e8f0;background:#ffffffd9;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-header{padding:.75rem 1.25rem}}.cortex-capture-form__multi-header-row{display:flex;align-items:flex-start;gap:.75rem}.cortex-capture-form__multi-icon{margin-top:.125rem;display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#475569}.cortex-capture-form__multi-icon-svg{width:1rem;height:1rem}.cortex-capture-form__multi-title-wrap{min-width:0}.cortex-capture-form__multi-title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#1e293b;margin:0}.cortex-capture-form__multi-subtitle{margin-top:.125rem;font-size:.6875rem;color:#64748b;margin-bottom:0}.cortex-capture-form__multi-fields{display:grid;gap:.75rem;padding:1rem;border:0}@media(min-width:640px){.cortex-capture-form__multi-fields{padding:1.25rem}}.cortex-capture-form__multi-item{border-radius:.75rem;border:1px solid #e2e8f0;background:#fff;padding:.75rem;transition:border-color .15s}.cortex-capture-form__multi-item:hover{border-color:#cbd5e1}.cortex-capture-form__multi-item-header{margin-bottom:.5rem;display:flex;align-items:center;justify-content:space-between;gap:.5rem}.cortex-capture-form__multi-item-label{display:block;font-size:.75rem;font-weight:500;line-height:1;color:#334155}.cortex-capture-form__required-badge{display:inline-flex;align-items:center;border-radius:.25rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.125rem .375rem;font-size:.625rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:#64748b}.cortex-capture-form__multi-footer{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;border-top:1px solid #e2e8f0;background:#ffffffe6;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-footer{padding:.75rem 1.25rem}}.cortex-capture-form__cancel-btn{display:inline-flex;align-items:center;border-radius:.375rem;border:1px solid #cbd5e1;background:#fff;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#475569;cursor:pointer;transition:background-color .15s}.cortex-capture-form__cancel-btn:hover{background:#f8fafc}.cortex-capture-form__cancel-btn:active{background:#f1f5f9}\n"], dependencies: [{ kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1$1.ɵNgNoValidate), selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i0.forwardRef(() => i1$1.DefaultValueAccessor), selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i0.forwardRef(() => i1$1.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1$1.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormArrayDirective), selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormGroupName), selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: i0.forwardRef(() => FileInputComponent), selector: "cortex-file-input", inputs: ["allowedMimeTypes"] }, { kind: "pipe", type: i0.forwardRef(() => TranslatePipe), name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
981
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageCaptureFilesPartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
982
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageCaptureFilesPartComponent, isStandalone: true, selector: "cortex-message-capture-files-part", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, toolPart: { classPropertyName: "toolPart", publicName: "toolPart", isSignal: true, isRequired: true, transformFunction: null }, setOutput: { classPropertyName: "setOutput", publicName: "setOutput", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "cortex-capture-files" }, ngImport: i0, template: "@if (outputData(); as output) {\n <!-- Result state -->\n @if (output.status === 'success') {\n <div class=\"cortex-capture-success\">\n <div class=\"cortex-capture-success__header\">\n <div class=\"cortex-capture-success__icon\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-success__icon-svg\" 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=\"cortex-capture-success__title-wrap\">\n <h3 class=\"cortex-capture-success__title\">\n {{ 'translate_files_attached' | translate: { count: requestedFiles().length } }}\n </h3>\n </div>\n </div>\n\n <div class=\"cortex-capture-success__file-list\">\n <ul class=\"cortex-capture-success__files\">\n @for (file of outputData()!.result!; track file.uploadId) {\n <li>\n <button\n type=\"button\"\n (click)=\"downloadFile(file.uploadId)\"\n class=\"cortex-capture-success__download-btn\"\n >\n <svg viewBox=\"0 0 16 16\" class=\"cortex-capture-success__file-icon\" 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=\"cortex-capture-success__file-name\">{{\n requestedFiles()[$index]?.label ?? outputData()!.result![$index]?.id\n }}</span>\n <svg viewBox=\"0 0 16 16\" class=\"cortex-capture-success__dl-icon\" 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=\"cortex-capture-canceled-wrap\">\n <div class=\"cortex-capture-canceled\">\n <div class=\"cortex-capture-canceled__icon\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-canceled__icon-svg\" fill=\"none\">\n <path d=\"M6 10h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </div>\n <span class=\"cortex-capture-canceled__text\">{{\n 'translate_file_upload_skipped' | translate\n }}</span>\n </div>\n </div>\n }\n} @else {\n @if (!hasInvalidInput()) {\n <!-- Upload form -->\n <form [formGroup]=\"form()\" class=\"cortex-capture-form\">\n @if (requestedFiles().length === 1) {\n <!-- Single file: minimal inline -->\n <fieldset [formArray]=\"form().controls.files\">\n <div [formGroupName]=\"0\" class=\"cortex-capture-form__single\">\n <label for=\"capture-file-0\" class=\"cortex-capture-form__label\">\n {{ requestedFiles()[0]!.label }}\n </label>\n <input hidden formControlName=\"id\" />\n <div class=\"cortex-capture-form__row\">\n <cortex-file-input\n id=\"capture-file-0\"\n formControlName=\"file\"\n class=\"cortex-capture-form__input\"\n />\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"cortex-capture-form__cancel-link\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"cortex-capture-form__submit-btn\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"cortex-capture-form__spinner\" 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=\"cortex-capture-form__spinner-track\"\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 class=\"cortex-capture-form__multi\">\n <div class=\"cortex-capture-form__multi-header\">\n <div class=\"cortex-capture-form__multi-header-row\">\n <div class=\"cortex-capture-form__multi-icon\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-form__multi-icon-svg\" 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=\"cortex-capture-form__multi-title-wrap\">\n <h3 class=\"cortex-capture-form__multi-title\">\n {{ 'translate_attach_requested_files' | translate }}\n </h3>\n <p class=\"cortex-capture-form__multi-subtitle\">\n {{ 'translate_n_files_required' | translate: { count: requestedFiles().length } }}\n </p>\n </div>\n </div>\n </div>\n\n <fieldset [formArray]=\"form().controls.files\" class=\"cortex-capture-form__multi-fields\">\n @for (file of form().controls.files.value; track $index) {\n <div [formGroupName]=\"$index\" class=\"cortex-capture-form__multi-item\">\n <div class=\"cortex-capture-form__multi-item-header\">\n <label\n [for]=\"'capture-file-' + $index\"\n class=\"cortex-capture-form__multi-item-label\"\n >\n {{ requestedFiles()[$index]!.label }}\n </label>\n <span class=\"cortex-capture-form__required-badge\">\n {{ 'translate_required' | translate }}\n </span>\n </div>\n <input hidden formControlName=\"id\" />\n <cortex-file-input [id]=\"'capture-file-' + $index\" formControlName=\"file\" />\n </div>\n }\n </fieldset>\n\n <div class=\"cortex-capture-form__multi-footer\">\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"cortex-capture-form__cancel-btn\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"cortex-capture-form__submit-btn\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"cortex-capture-form__spinner\" 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=\"cortex-capture-form__spinner-track\"\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}\n", styles: [".cortex-capture-files{display:block;width:100%}.cortex-file-input{display:flex;width:100%;cursor:pointer;align-items:center;border-radius:.5rem;border:1px solid #cbd5e1;background:#f8fafc;transition:border-color .15s}.cortex-file-input:hover{border-color:#94a3b8}.cortex-file-input:focus-within{box-shadow:0 0 0 2px #cbd5e1}.cortex-file-input__btn{margin:.25rem;flex-shrink:0;cursor:pointer;border-radius:.375rem;border:0;background:#1e293b;padding:.375rem .75rem;font-size:.6875rem;font-weight:600;letter-spacing:.025em;color:#f1f5f9}.cortex-file-input__btn:hover{background:#334155}.cortex-file-input__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 .75rem;font-size:.75rem;color:#475569}.cortex-file-input__hidden{display:none}.cortex-capture-success{overflow:hidden;border-radius:1rem;border:1px solid #a7f3d0;background:linear-gradient(to bottom,#ecfdf5cc,#fff)}.cortex-capture-success__header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-success__header{padding:.75rem 1.25rem}}.cortex-capture-success__icon{display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #a7f3d0;background:#d1fae5;color:#059669}.cortex-capture-success__icon-svg{width:1rem;height:1rem}.cortex-capture-success__title-wrap{min-width:0}.cortex-capture-success__title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#065f46;margin:0}.cortex-capture-success__file-list{border-top:1px solid #d1fae5;padding:.625rem 1rem}@media(min-width:640px){.cortex-capture-success__file-list{padding:.625rem 1.25rem}}.cortex-capture-success__files{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;margin:0;padding:0}.cortex-capture-success__download-btn{display:inline-flex;cursor:pointer;align-items:center;gap:.375rem;border-radius:.5rem;border:1px solid #d1fae5;background:#fff;padding:.375rem .625rem;font-size:.75rem;font-weight:500;color:#047857;box-shadow:0 1px 2px #0000000d;transition:all .15s}.cortex-capture-success__download-btn:hover{border-color:#a7f3d0;background:#ecfdf5;box-shadow:0 1px 3px #0000001a}.cortex-capture-success__download-btn:active{transform:scale(.97)}.cortex-capture-success__file-icon{width:.875rem;height:.875rem;flex-shrink:0;color:#6ee7b7}.cortex-capture-success__file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.cortex-capture-success__dl-icon{width:.75rem;height:.75rem;flex-shrink:0;color:#86efac}.cortex-capture-canceled-wrap{display:flex;justify-content:center}.cortex-capture-canceled{display:inline-flex;align-items:center;gap:.625rem;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.625rem 1rem}.cortex-capture-canceled__icon{display:inline-flex;width:1.5rem;height:1.5rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#94a3b8}.cortex-capture-canceled__icon-svg{width:.75rem;height:.75rem}.cortex-capture-canceled__text{font-size:.8125rem;font-weight:500;color:#94a3b8}.cortex-capture-form{width:100%}.cortex-capture-form__single{border-radius:.75rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.75rem}.cortex-capture-form__label{display:block;margin-bottom:.375rem;font-size:.75rem;color:#64748b}.cortex-capture-form__row{display:flex;align-items:center;gap:.5rem}.cortex-capture-form__input{min-width:0;flex:1}.cortex-capture-form__cancel-link{flex-shrink:0;font-size:.75rem;font-weight:500;color:#94a3b8;background:none;border:0;cursor:pointer;transition:color .15s}.cortex-capture-form__cancel-link:hover{color:#475569}.cortex-capture-form__submit-btn{display:inline-flex;flex-shrink:0;align-items:center;border-radius:.375rem;background:#1e293b;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#f1f5f9;border:0;cursor:pointer;transition:background-color .15s}.cortex-capture-form__submit-btn:hover{background:#334155}.cortex-capture-form__submit-btn:active{background:#0f172a}.cortex-capture-form__submit-btn:disabled{cursor:not-allowed;background:#cbd5e1}.cortex-capture-form__spinner{width:.75rem;height:.75rem;margin-inline-end:.375rem;animation:cortex-capture-spin .8s linear infinite}.cortex-capture-form__spinner-track{opacity:.25}@keyframes cortex-capture-spin{to{transform:rotate(360deg)}}.cortex-capture-form__multi{overflow:hidden;border-radius:1rem;border:1px solid #e2e8f0;background:linear-gradient(to bottom,#fff,#f8fafc)}.cortex-capture-form__multi-header{border-bottom:1px solid #e2e8f0;background:#ffffffd9;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-header{padding:.75rem 1.25rem}}.cortex-capture-form__multi-header-row{display:flex;align-items:flex-start;gap:.75rem}.cortex-capture-form__multi-icon{margin-top:.125rem;display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#475569}.cortex-capture-form__multi-icon-svg{width:1rem;height:1rem}.cortex-capture-form__multi-title-wrap{min-width:0}.cortex-capture-form__multi-title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#1e293b;margin:0}.cortex-capture-form__multi-subtitle{margin-top:.125rem;font-size:.6875rem;color:#64748b;margin-bottom:0}.cortex-capture-form__multi-fields{display:grid;gap:.75rem;padding:1rem;border:0}@media(min-width:640px){.cortex-capture-form__multi-fields{padding:1.25rem}}.cortex-capture-form__multi-item{border-radius:.75rem;border:1px solid #e2e8f0;background:#fff;padding:.75rem;transition:border-color .15s}.cortex-capture-form__multi-item:hover{border-color:#cbd5e1}.cortex-capture-form__multi-item-header{margin-bottom:.5rem;display:flex;align-items:center;justify-content:space-between;gap:.5rem}.cortex-capture-form__multi-item-label{display:block;font-size:.75rem;font-weight:500;line-height:1;color:#334155}.cortex-capture-form__required-badge{display:inline-flex;align-items:center;border-radius:.25rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.125rem .375rem;font-size:.625rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:#64748b}.cortex-capture-form__multi-footer{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;border-top:1px solid #e2e8f0;background:#ffffffe6;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-footer{padding:.75rem 1.25rem}}.cortex-capture-form__cancel-btn{display:inline-flex;align-items:center;border-radius:.375rem;border:1px solid #cbd5e1;background:#fff;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#475569;cursor:pointer;transition:background-color .15s}.cortex-capture-form__cancel-btn:hover{background:#f8fafc}.cortex-capture-form__cancel-btn:active{background:#f1f5f9}\n"], dependencies: [{ kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "directive", type: i0.forwardRef(() => i1$1.ɵNgNoValidate), selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i0.forwardRef(() => i1$1.DefaultValueAccessor), selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i0.forwardRef(() => i1$1.NgControlStatus), selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i0.forwardRef(() => i1$1.NgControlStatusGroup), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormGroupDirective), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormArrayDirective), selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormControlName), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i0.forwardRef(() => i1$1.FormGroupName), selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: i0.forwardRef(() => FileInputComponent), selector: "cortex-file-input", inputs: ["allowedMimeTypes"] }, { kind: "pipe", type: i0.forwardRef(() => TranslatePipe), name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
756
983
|
}
|
|
757
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
984
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageCaptureFilesPartComponent, decorators: [{
|
|
758
985
|
type: Component,
|
|
759
986
|
args: [{ selector: 'cortex-message-capture-files-part', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [ReactiveFormsModule, forwardRef(() => FileInputComponent), TranslatePipe], host: { class: 'cortex-capture-files' }, template: "@if (outputData(); as output) {\n <!-- Result state -->\n @if (output.status === 'success') {\n <div class=\"cortex-capture-success\">\n <div class=\"cortex-capture-success__header\">\n <div class=\"cortex-capture-success__icon\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-success__icon-svg\" 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=\"cortex-capture-success__title-wrap\">\n <h3 class=\"cortex-capture-success__title\">\n {{ 'translate_files_attached' | translate: { count: requestedFiles().length } }}\n </h3>\n </div>\n </div>\n\n <div class=\"cortex-capture-success__file-list\">\n <ul class=\"cortex-capture-success__files\">\n @for (file of outputData()!.result!; track file.uploadId) {\n <li>\n <button\n type=\"button\"\n (click)=\"downloadFile(file.uploadId)\"\n class=\"cortex-capture-success__download-btn\"\n >\n <svg viewBox=\"0 0 16 16\" class=\"cortex-capture-success__file-icon\" 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=\"cortex-capture-success__file-name\">{{\n requestedFiles()[$index]?.label ?? outputData()!.result![$index]?.id\n }}</span>\n <svg viewBox=\"0 0 16 16\" class=\"cortex-capture-success__dl-icon\" 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=\"cortex-capture-canceled-wrap\">\n <div class=\"cortex-capture-canceled\">\n <div class=\"cortex-capture-canceled__icon\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-canceled__icon-svg\" fill=\"none\">\n <path d=\"M6 10h8\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n </div>\n <span class=\"cortex-capture-canceled__text\">{{\n 'translate_file_upload_skipped' | translate\n }}</span>\n </div>\n </div>\n }\n} @else {\n @if (!hasInvalidInput()) {\n <!-- Upload form -->\n <form [formGroup]=\"form()\" class=\"cortex-capture-form\">\n @if (requestedFiles().length === 1) {\n <!-- Single file: minimal inline -->\n <fieldset [formArray]=\"form().controls.files\">\n <div [formGroupName]=\"0\" class=\"cortex-capture-form__single\">\n <label for=\"capture-file-0\" class=\"cortex-capture-form__label\">\n {{ requestedFiles()[0]!.label }}\n </label>\n <input hidden formControlName=\"id\" />\n <div class=\"cortex-capture-form__row\">\n <cortex-file-input\n id=\"capture-file-0\"\n formControlName=\"file\"\n class=\"cortex-capture-form__input\"\n />\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"cortex-capture-form__cancel-link\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"cortex-capture-form__submit-btn\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"cortex-capture-form__spinner\" 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=\"cortex-capture-form__spinner-track\"\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 class=\"cortex-capture-form__multi\">\n <div class=\"cortex-capture-form__multi-header\">\n <div class=\"cortex-capture-form__multi-header-row\">\n <div class=\"cortex-capture-form__multi-icon\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 20 20\" class=\"cortex-capture-form__multi-icon-svg\" 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=\"cortex-capture-form__multi-title-wrap\">\n <h3 class=\"cortex-capture-form__multi-title\">\n {{ 'translate_attach_requested_files' | translate }}\n </h3>\n <p class=\"cortex-capture-form__multi-subtitle\">\n {{ 'translate_n_files_required' | translate: { count: requestedFiles().length } }}\n </p>\n </div>\n </div>\n </div>\n\n <fieldset [formArray]=\"form().controls.files\" class=\"cortex-capture-form__multi-fields\">\n @for (file of form().controls.files.value; track $index) {\n <div [formGroupName]=\"$index\" class=\"cortex-capture-form__multi-item\">\n <div class=\"cortex-capture-form__multi-item-header\">\n <label\n [for]=\"'capture-file-' + $index\"\n class=\"cortex-capture-form__multi-item-label\"\n >\n {{ requestedFiles()[$index]!.label }}\n </label>\n <span class=\"cortex-capture-form__required-badge\">\n {{ 'translate_required' | translate }}\n </span>\n </div>\n <input hidden formControlName=\"id\" />\n <cortex-file-input [id]=\"'capture-file-' + $index\" formControlName=\"file\" />\n </div>\n }\n </fieldset>\n\n <div class=\"cortex-capture-form__multi-footer\">\n <button\n (click)=\"cancel()\"\n [disabled]=\"isLoading()\"\n type=\"button\"\n class=\"cortex-capture-form__cancel-btn\"\n >\n {{ 'translate_cancel' | translate }}\n </button>\n <button\n (click)=\"submit()\"\n type=\"button\"\n class=\"cortex-capture-form__submit-btn\"\n [disabled]=\"form().invalid || isLoading()\"\n >\n @if (isLoading()) {\n <svg class=\"cortex-capture-form__spinner\" 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=\"cortex-capture-form__spinner-track\"\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}\n", styles: [".cortex-capture-files{display:block;width:100%}.cortex-file-input{display:flex;width:100%;cursor:pointer;align-items:center;border-radius:.5rem;border:1px solid #cbd5e1;background:#f8fafc;transition:border-color .15s}.cortex-file-input:hover{border-color:#94a3b8}.cortex-file-input:focus-within{box-shadow:0 0 0 2px #cbd5e1}.cortex-file-input__btn{margin:.25rem;flex-shrink:0;cursor:pointer;border-radius:.375rem;border:0;background:#1e293b;padding:.375rem .75rem;font-size:.6875rem;font-weight:600;letter-spacing:.025em;color:#f1f5f9}.cortex-file-input__btn:hover{background:#334155}.cortex-file-input__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 .75rem;font-size:.75rem;color:#475569}.cortex-file-input__hidden{display:none}.cortex-capture-success{overflow:hidden;border-radius:1rem;border:1px solid #a7f3d0;background:linear-gradient(to bottom,#ecfdf5cc,#fff)}.cortex-capture-success__header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-success__header{padding:.75rem 1.25rem}}.cortex-capture-success__icon{display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #a7f3d0;background:#d1fae5;color:#059669}.cortex-capture-success__icon-svg{width:1rem;height:1rem}.cortex-capture-success__title-wrap{min-width:0}.cortex-capture-success__title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#065f46;margin:0}.cortex-capture-success__file-list{border-top:1px solid #d1fae5;padding:.625rem 1rem}@media(min-width:640px){.cortex-capture-success__file-list{padding:.625rem 1.25rem}}.cortex-capture-success__files{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;margin:0;padding:0}.cortex-capture-success__download-btn{display:inline-flex;cursor:pointer;align-items:center;gap:.375rem;border-radius:.5rem;border:1px solid #d1fae5;background:#fff;padding:.375rem .625rem;font-size:.75rem;font-weight:500;color:#047857;box-shadow:0 1px 2px #0000000d;transition:all .15s}.cortex-capture-success__download-btn:hover{border-color:#a7f3d0;background:#ecfdf5;box-shadow:0 1px 3px #0000001a}.cortex-capture-success__download-btn:active{transform:scale(.97)}.cortex-capture-success__file-icon{width:.875rem;height:.875rem;flex-shrink:0;color:#6ee7b7}.cortex-capture-success__file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.cortex-capture-success__dl-icon{width:.75rem;height:.75rem;flex-shrink:0;color:#86efac}.cortex-capture-canceled-wrap{display:flex;justify-content:center}.cortex-capture-canceled{display:inline-flex;align-items:center;gap:.625rem;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.625rem 1rem}.cortex-capture-canceled__icon{display:inline-flex;width:1.5rem;height:1.5rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#94a3b8}.cortex-capture-canceled__icon-svg{width:.75rem;height:.75rem}.cortex-capture-canceled__text{font-size:.8125rem;font-weight:500;color:#94a3b8}.cortex-capture-form{width:100%}.cortex-capture-form__single{border-radius:.75rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.75rem}.cortex-capture-form__label{display:block;margin-bottom:.375rem;font-size:.75rem;color:#64748b}.cortex-capture-form__row{display:flex;align-items:center;gap:.5rem}.cortex-capture-form__input{min-width:0;flex:1}.cortex-capture-form__cancel-link{flex-shrink:0;font-size:.75rem;font-weight:500;color:#94a3b8;background:none;border:0;cursor:pointer;transition:color .15s}.cortex-capture-form__cancel-link:hover{color:#475569}.cortex-capture-form__submit-btn{display:inline-flex;flex-shrink:0;align-items:center;border-radius:.375rem;background:#1e293b;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#f1f5f9;border:0;cursor:pointer;transition:background-color .15s}.cortex-capture-form__submit-btn:hover{background:#334155}.cortex-capture-form__submit-btn:active{background:#0f172a}.cortex-capture-form__submit-btn:disabled{cursor:not-allowed;background:#cbd5e1}.cortex-capture-form__spinner{width:.75rem;height:.75rem;margin-inline-end:.375rem;animation:cortex-capture-spin .8s linear infinite}.cortex-capture-form__spinner-track{opacity:.25}@keyframes cortex-capture-spin{to{transform:rotate(360deg)}}.cortex-capture-form__multi{overflow:hidden;border-radius:1rem;border:1px solid #e2e8f0;background:linear-gradient(to bottom,#fff,#f8fafc)}.cortex-capture-form__multi-header{border-bottom:1px solid #e2e8f0;background:#ffffffd9;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-header{padding:.75rem 1.25rem}}.cortex-capture-form__multi-header-row{display:flex;align-items:flex-start;gap:.75rem}.cortex-capture-form__multi-icon{margin-top:.125rem;display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#475569}.cortex-capture-form__multi-icon-svg{width:1rem;height:1rem}.cortex-capture-form__multi-title-wrap{min-width:0}.cortex-capture-form__multi-title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#1e293b;margin:0}.cortex-capture-form__multi-subtitle{margin-top:.125rem;font-size:.6875rem;color:#64748b;margin-bottom:0}.cortex-capture-form__multi-fields{display:grid;gap:.75rem;padding:1rem;border:0}@media(min-width:640px){.cortex-capture-form__multi-fields{padding:1.25rem}}.cortex-capture-form__multi-item{border-radius:.75rem;border:1px solid #e2e8f0;background:#fff;padding:.75rem;transition:border-color .15s}.cortex-capture-form__multi-item:hover{border-color:#cbd5e1}.cortex-capture-form__multi-item-header{margin-bottom:.5rem;display:flex;align-items:center;justify-content:space-between;gap:.5rem}.cortex-capture-form__multi-item-label{display:block;font-size:.75rem;font-weight:500;line-height:1;color:#334155}.cortex-capture-form__required-badge{display:inline-flex;align-items:center;border-radius:.25rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.125rem .375rem;font-size:.625rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:#64748b}.cortex-capture-form__multi-footer{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;border-top:1px solid #e2e8f0;background:#ffffffe6;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-footer{padding:.75rem 1.25rem}}.cortex-capture-form__cancel-btn{display:inline-flex;align-items:center;border-radius:.375rem;border:1px solid #cbd5e1;background:#fff;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#475569;cursor:pointer;transition:background-color .15s}.cortex-capture-form__cancel-btn:hover{background:#f8fafc}.cortex-capture-form__cancel-btn:active{background:#f1f5f9}\n"] }]
|
|
760
987
|
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], toolPart: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolPart", required: true }] }], setOutput: [{ type: i0.Input, args: [{ isSignal: true, alias: "setOutput", required: true }] }] } });
|
|
@@ -808,8 +1035,8 @@ class FileInputComponent {
|
|
|
808
1035
|
this.value.set(value);
|
|
809
1036
|
this.onChange?.(value);
|
|
810
1037
|
}
|
|
811
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
812
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
1038
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: FileInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1039
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: FileInputComponent, isStandalone: true, selector: "cortex-file-input", inputs: { allowedMimeTypes: { classPropertyName: "allowedMimeTypes", publicName: "allowedMimeTypes", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
813
1040
|
{
|
|
814
1041
|
provide: NG_VALUE_ACCESSOR,
|
|
815
1042
|
multi: true,
|
|
@@ -825,7 +1052,7 @@ class FileInputComponent {
|
|
|
825
1052
|
<input #fileInput (change)="loadFile($event)" type="file" class="cortex-file-input__hidden" />
|
|
826
1053
|
</div>`, isInline: true, styles: [".cortex-capture-files{display:block;width:100%}.cortex-file-input{display:flex;width:100%;cursor:pointer;align-items:center;border-radius:.5rem;border:1px solid #cbd5e1;background:#f8fafc;transition:border-color .15s}.cortex-file-input:hover{border-color:#94a3b8}.cortex-file-input:focus-within{box-shadow:0 0 0 2px #cbd5e1}.cortex-file-input__btn{margin:.25rem;flex-shrink:0;cursor:pointer;border-radius:.375rem;border:0;background:#1e293b;padding:.375rem .75rem;font-size:.6875rem;font-weight:600;letter-spacing:.025em;color:#f1f5f9}.cortex-file-input__btn:hover{background:#334155}.cortex-file-input__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 .75rem;font-size:.75rem;color:#475569}.cortex-file-input__hidden{display:none}.cortex-capture-success{overflow:hidden;border-radius:1rem;border:1px solid #a7f3d0;background:linear-gradient(to bottom,#ecfdf5cc,#fff)}.cortex-capture-success__header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-success__header{padding:.75rem 1.25rem}}.cortex-capture-success__icon{display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #a7f3d0;background:#d1fae5;color:#059669}.cortex-capture-success__icon-svg{width:1rem;height:1rem}.cortex-capture-success__title-wrap{min-width:0}.cortex-capture-success__title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#065f46;margin:0}.cortex-capture-success__file-list{border-top:1px solid #d1fae5;padding:.625rem 1rem}@media(min-width:640px){.cortex-capture-success__file-list{padding:.625rem 1.25rem}}.cortex-capture-success__files{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;margin:0;padding:0}.cortex-capture-success__download-btn{display:inline-flex;cursor:pointer;align-items:center;gap:.375rem;border-radius:.5rem;border:1px solid #d1fae5;background:#fff;padding:.375rem .625rem;font-size:.75rem;font-weight:500;color:#047857;box-shadow:0 1px 2px #0000000d;transition:all .15s}.cortex-capture-success__download-btn:hover{border-color:#a7f3d0;background:#ecfdf5;box-shadow:0 1px 3px #0000001a}.cortex-capture-success__download-btn:active{transform:scale(.97)}.cortex-capture-success__file-icon{width:.875rem;height:.875rem;flex-shrink:0;color:#6ee7b7}.cortex-capture-success__file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:180px}.cortex-capture-success__dl-icon{width:.75rem;height:.75rem;flex-shrink:0;color:#86efac}.cortex-capture-canceled-wrap{display:flex;justify-content:center}.cortex-capture-canceled{display:inline-flex;align-items:center;gap:.625rem;border-radius:.5rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.625rem 1rem}.cortex-capture-canceled__icon{display:inline-flex;width:1.5rem;height:1.5rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#94a3b8}.cortex-capture-canceled__icon-svg{width:.75rem;height:.75rem}.cortex-capture-canceled__text{font-size:.8125rem;font-weight:500;color:#94a3b8}.cortex-capture-form{width:100%}.cortex-capture-form__single{border-radius:.75rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.75rem}.cortex-capture-form__label{display:block;margin-bottom:.375rem;font-size:.75rem;color:#64748b}.cortex-capture-form__row{display:flex;align-items:center;gap:.5rem}.cortex-capture-form__input{min-width:0;flex:1}.cortex-capture-form__cancel-link{flex-shrink:0;font-size:.75rem;font-weight:500;color:#94a3b8;background:none;border:0;cursor:pointer;transition:color .15s}.cortex-capture-form__cancel-link:hover{color:#475569}.cortex-capture-form__submit-btn{display:inline-flex;flex-shrink:0;align-items:center;border-radius:.375rem;background:#1e293b;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#f1f5f9;border:0;cursor:pointer;transition:background-color .15s}.cortex-capture-form__submit-btn:hover{background:#334155}.cortex-capture-form__submit-btn:active{background:#0f172a}.cortex-capture-form__submit-btn:disabled{cursor:not-allowed;background:#cbd5e1}.cortex-capture-form__spinner{width:.75rem;height:.75rem;margin-inline-end:.375rem;animation:cortex-capture-spin .8s linear infinite}.cortex-capture-form__spinner-track{opacity:.25}@keyframes cortex-capture-spin{to{transform:rotate(360deg)}}.cortex-capture-form__multi{overflow:hidden;border-radius:1rem;border:1px solid #e2e8f0;background:linear-gradient(to bottom,#fff,#f8fafc)}.cortex-capture-form__multi-header{border-bottom:1px solid #e2e8f0;background:#ffffffd9;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-header{padding:.75rem 1.25rem}}.cortex-capture-form__multi-header-row{display:flex;align-items:flex-start;gap:.75rem}.cortex-capture-form__multi-icon{margin-top:.125rem;display:inline-flex;width:2rem;height:2rem;flex-shrink:0;align-items:center;justify-content:center;border-radius:.5rem;border:1px solid #e2e8f0;background:#f1f5f9;color:#475569}.cortex-capture-form__multi-icon-svg{width:1rem;height:1rem}.cortex-capture-form__multi-title-wrap{min-width:0}.cortex-capture-form__multi-title{font-size:.8125rem;font-weight:600;letter-spacing:-.01em;color:#1e293b;margin:0}.cortex-capture-form__multi-subtitle{margin-top:.125rem;font-size:.6875rem;color:#64748b;margin-bottom:0}.cortex-capture-form__multi-fields{display:grid;gap:.75rem;padding:1rem;border:0}@media(min-width:640px){.cortex-capture-form__multi-fields{padding:1.25rem}}.cortex-capture-form__multi-item{border-radius:.75rem;border:1px solid #e2e8f0;background:#fff;padding:.75rem;transition:border-color .15s}.cortex-capture-form__multi-item:hover{border-color:#cbd5e1}.cortex-capture-form__multi-item-header{margin-bottom:.5rem;display:flex;align-items:center;justify-content:space-between;gap:.5rem}.cortex-capture-form__multi-item-label{display:block;font-size:.75rem;font-weight:500;line-height:1;color:#334155}.cortex-capture-form__required-badge{display:inline-flex;align-items:center;border-radius:.25rem;border:1px solid #e2e8f0;background:#f8fafc;padding:.125rem .375rem;font-size:.625rem;font-weight:500;text-transform:uppercase;letter-spacing:.05em;color:#64748b}.cortex-capture-form__multi-footer{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;border-top:1px solid #e2e8f0;background:#ffffffe6;padding:.75rem 1rem}@media(min-width:640px){.cortex-capture-form__multi-footer{padding:.75rem 1.25rem}}.cortex-capture-form__cancel-btn{display:inline-flex;align-items:center;border-radius:.375rem;border:1px solid #cbd5e1;background:#fff;padding:.375rem .75rem;font-size:.75rem;font-weight:500;color:#475569;cursor:pointer;transition:background-color .15s}.cortex-capture-form__cancel-btn:hover{background:#f8fafc}.cortex-capture-form__cancel-btn:active{background:#f1f5f9}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
827
1054
|
}
|
|
828
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1055
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: FileInputComponent, decorators: [{
|
|
829
1056
|
type: Component,
|
|
830
1057
|
args: [{ selector: 'cortex-file-input', template: `<div class="cortex-file-input">
|
|
831
1058
|
<button type="button" (click)="fileInput.click()" class="cortex-file-input__btn">
|
|
@@ -931,10 +1158,10 @@ class MessageToolCallAnimatedComponent {
|
|
|
931
1158
|
return Math.abs(hash) % STATUS_COUNT;
|
|
932
1159
|
}, ...(ngDevMode ? [{ debugName: "stableIndex" }] : /* istanbul ignore next */ []));
|
|
933
1160
|
chatService = inject(CortexChatService);
|
|
934
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
935
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1161
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageToolCallAnimatedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1162
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageToolCallAnimatedComponent, isStandalone: true, selector: "cortex-message-tool-call-animated", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, toolCallPart: { classPropertyName: "toolCallPart", publicName: "toolCallPart", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "cortex-tool-call-animated" }, ngImport: i0, template: "@if (customComponent(); as custom) {\n <ng-container\n *ngComponentOutlet=\"\n custom;\n inputs: { toolCallPart: toolCallPart(), message: message(), setOutput: setOutput() };\n injector: config.injector\n \"\n />\n} @else {\n @switch (toolCallPart().type) {\n @case ('tool-captureFiles') {\n <cortex-message-capture-files-part\n [toolPart]=\"toolCallPart()\"\n [message]=\"message()\"\n [setOutput]=\"setOutput()\"\n />\n }\n @default {\n @let state = animState();\n @let active = isActive();\n\n <div class=\"cortex-tool-pill-wrap\">\n <div\n class=\"cortex-tool-pill\"\n [class.cortex-tool-pill--active]=\"active\"\n [class.cortex-tool-pill--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill--error]=\"state === 'error'\"\n [class.cortex-tool-pill--denied]=\"state === 'denied'\"\n >\n <!-- Icon box -->\n <div\n class=\"cortex-tool-pill__icon\"\n [class.cortex-tool-pill__icon--active]=\"active\"\n [class.cortex-tool-pill__icon--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill__icon--error]=\"state === 'error'\"\n [class.cortex-tool-pill__icon--denied]=\"state === 'denied'\"\n >\n <!-- Spinner -->\n <div\n class=\"cortex-tool-pill__spinner\"\n [class.cortex-tool-pill__spinner--visible]=\"active\"\n ></div>\n <!-- Check -->\n <svg\n class=\"cortex-tool-pill__svg\"\n [class.cortex-tool-pill__svg--visible]=\"state === 'complete'\"\n [class.cortex-tool-pill__svg--check]=\"state === 'complete'\"\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=\"cortex-tool-pill__svg\"\n [class.cortex-tool-pill__svg--visible]=\"state === 'error'\"\n [class.cortex-tool-pill__svg--error]=\"state === 'error'\"\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=\"cortex-tool-pill__svg\"\n [class.cortex-tool-pill__svg--visible]=\"state === 'denied'\"\n [class.cortex-tool-pill__svg--denied]=\"state === 'denied'\"\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=\"cortex-tool-pill__title\"\n [class.cortex-tool-pill__title--active]=\"active\"\n [class.cortex-tool-pill__title--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill__title--error]=\"state === 'error'\"\n [class.cortex-tool-pill__title--denied]=\"state === 'denied'\"\n >\n {{ displayTitleKey() | translate }}\n </span>\n\n <!-- Bottom bar -->\n <div class=\"cortex-tool-pill__bar-track\">\n <div\n class=\"cortex-tool-pill__bar\"\n [class.cortex-tool-pill__bar--active]=\"active\"\n [class.cortex-tool-pill__bar--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill__bar--error]=\"state === 'error'\"\n [class.cortex-tool-pill__bar--denied]=\"state === 'denied'\"\n ></div>\n </div>\n </div>\n </div>\n }\n }\n}\n", styles: [".cortex-tool-call-animated{display:block;width:100%}.cortex-tool-pill-wrap{display:flex;justify-content:center}.cortex-tool-pill{display:inline-flex;align-items:center;gap:.625rem;padding:.625rem 1rem;border-radius:.5rem;border:1px solid;position:relative;overflow:hidden;transition:background-color .3s,border-color .3s}.cortex-tool-pill--active{border-color:#c7d2fe;background:#eef2ff}.cortex-tool-pill--complete{border-color:#a7f3d0;background:#ecfdf5}.cortex-tool-pill--error{border-color:#fecaca;background:#fef2f2}.cortex-tool-pill--denied{border-color:#e2e8f0;background:#f8fafc;opacity:.6}.cortex-tool-pill__icon{position:relative;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid;flex-shrink:0;transition:background-color .3s,border-color .3s}.cortex-tool-pill__icon--active{background:#e0e7ff;border-color:#c7d2fe}.cortex-tool-pill__icon--complete{background:#d1fae5;border-color:#a7f3d0}.cortex-tool-pill__icon--error{background:#fee2e2;border-color:#fecaca}.cortex-tool-pill__icon--denied{background:#f1f5f9;border-color:#e2e8f0}.cortex-tool-pill__spinner{position:absolute;width:.75rem;height:.75rem;border:1.5px solid #c7d2fe;border-top-color:#6366f1;border-radius:9999px;opacity:0;transition:opacity .2s}.cortex-tool-pill__spinner--visible{opacity:1;animation:cortex-tool-spin .8s linear infinite}@keyframes cortex-tool-spin{to{transform:rotate(360deg)}}.cortex-tool-pill__svg{position:absolute;width:.75rem;height:.75rem;opacity:0;transform:scale(.6);transition:opacity .2s,transform .2s}.cortex-tool-pill__svg--visible{opacity:1;transform:scale(1)}.cortex-tool-pill__svg--check{color:#059669}.cortex-tool-pill__svg--error{color:#dc2626}.cortex-tool-pill__svg--denied{color:#94a3b8}.cortex-tool-pill__title{font-size:.8125rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .3s}.cortex-tool-pill__title--active{color:#4338ca}.cortex-tool-pill__title--complete{color:#047857}.cortex-tool-pill__title--error{color:#dc2626}.cortex-tool-pill__title--denied{color:#94a3b8}.cortex-tool-pill__bar-track{position:absolute;bottom:0;left:0;right:0;height:2px;overflow:hidden}.cortex-tool-pill__bar{height:100%;width:100%;transform-origin:left}.cortex-tool-pill__bar--active{background:#818cf8;animation:cortex-bar-slide 1.5s ease-in-out infinite}.cortex-tool-pill__bar--complete{background:#34d399;animation:cortex-bar-fill .3s ease-out both}.cortex-tool-pill__bar--error{background:#f87171;animation:cortex-bar-fill .3s ease-out both}.cortex-tool-pill__bar--denied{opacity:0}@keyframes cortex-bar-slide{0%{transform:translate(-100%)}to{transform:translate(100%)}}@keyframes cortex-bar-fill{0%{transform:scaleX(0)}to{transform:scaleX(1)}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: MessageCaptureFilesPartComponent, selector: "cortex-message-capture-files-part", inputs: ["message", "toolPart", "setOutput"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
936
1163
|
}
|
|
937
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1164
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageToolCallAnimatedComponent, decorators: [{
|
|
938
1165
|
type: Component,
|
|
939
1166
|
args: [{ selector: 'cortex-message-tool-call-animated', imports: [NgComponentOutlet, MessageCaptureFilesPartComponent, TranslatePipe], host: { class: 'cortex-tool-call-animated' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (customComponent(); as custom) {\n <ng-container\n *ngComponentOutlet=\"\n custom;\n inputs: { toolCallPart: toolCallPart(), message: message(), setOutput: setOutput() };\n injector: config.injector\n \"\n />\n} @else {\n @switch (toolCallPart().type) {\n @case ('tool-captureFiles') {\n <cortex-message-capture-files-part\n [toolPart]=\"toolCallPart()\"\n [message]=\"message()\"\n [setOutput]=\"setOutput()\"\n />\n }\n @default {\n @let state = animState();\n @let active = isActive();\n\n <div class=\"cortex-tool-pill-wrap\">\n <div\n class=\"cortex-tool-pill\"\n [class.cortex-tool-pill--active]=\"active\"\n [class.cortex-tool-pill--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill--error]=\"state === 'error'\"\n [class.cortex-tool-pill--denied]=\"state === 'denied'\"\n >\n <!-- Icon box -->\n <div\n class=\"cortex-tool-pill__icon\"\n [class.cortex-tool-pill__icon--active]=\"active\"\n [class.cortex-tool-pill__icon--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill__icon--error]=\"state === 'error'\"\n [class.cortex-tool-pill__icon--denied]=\"state === 'denied'\"\n >\n <!-- Spinner -->\n <div\n class=\"cortex-tool-pill__spinner\"\n [class.cortex-tool-pill__spinner--visible]=\"active\"\n ></div>\n <!-- Check -->\n <svg\n class=\"cortex-tool-pill__svg\"\n [class.cortex-tool-pill__svg--visible]=\"state === 'complete'\"\n [class.cortex-tool-pill__svg--check]=\"state === 'complete'\"\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=\"cortex-tool-pill__svg\"\n [class.cortex-tool-pill__svg--visible]=\"state === 'error'\"\n [class.cortex-tool-pill__svg--error]=\"state === 'error'\"\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=\"cortex-tool-pill__svg\"\n [class.cortex-tool-pill__svg--visible]=\"state === 'denied'\"\n [class.cortex-tool-pill__svg--denied]=\"state === 'denied'\"\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=\"cortex-tool-pill__title\"\n [class.cortex-tool-pill__title--active]=\"active\"\n [class.cortex-tool-pill__title--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill__title--error]=\"state === 'error'\"\n [class.cortex-tool-pill__title--denied]=\"state === 'denied'\"\n >\n {{ displayTitleKey() | translate }}\n </span>\n\n <!-- Bottom bar -->\n <div class=\"cortex-tool-pill__bar-track\">\n <div\n class=\"cortex-tool-pill__bar\"\n [class.cortex-tool-pill__bar--active]=\"active\"\n [class.cortex-tool-pill__bar--complete]=\"state === 'complete'\"\n [class.cortex-tool-pill__bar--error]=\"state === 'error'\"\n [class.cortex-tool-pill__bar--denied]=\"state === 'denied'\"\n ></div>\n </div>\n </div>\n </div>\n }\n }\n}\n", styles: [".cortex-tool-call-animated{display:block;width:100%}.cortex-tool-pill-wrap{display:flex;justify-content:center}.cortex-tool-pill{display:inline-flex;align-items:center;gap:.625rem;padding:.625rem 1rem;border-radius:.5rem;border:1px solid;position:relative;overflow:hidden;transition:background-color .3s,border-color .3s}.cortex-tool-pill--active{border-color:#c7d2fe;background:#eef2ff}.cortex-tool-pill--complete{border-color:#a7f3d0;background:#ecfdf5}.cortex-tool-pill--error{border-color:#fecaca;background:#fef2f2}.cortex-tool-pill--denied{border-color:#e2e8f0;background:#f8fafc;opacity:.6}.cortex-tool-pill__icon{position:relative;width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;border-radius:.375rem;border:1px solid;flex-shrink:0;transition:background-color .3s,border-color .3s}.cortex-tool-pill__icon--active{background:#e0e7ff;border-color:#c7d2fe}.cortex-tool-pill__icon--complete{background:#d1fae5;border-color:#a7f3d0}.cortex-tool-pill__icon--error{background:#fee2e2;border-color:#fecaca}.cortex-tool-pill__icon--denied{background:#f1f5f9;border-color:#e2e8f0}.cortex-tool-pill__spinner{position:absolute;width:.75rem;height:.75rem;border:1.5px solid #c7d2fe;border-top-color:#6366f1;border-radius:9999px;opacity:0;transition:opacity .2s}.cortex-tool-pill__spinner--visible{opacity:1;animation:cortex-tool-spin .8s linear infinite}@keyframes cortex-tool-spin{to{transform:rotate(360deg)}}.cortex-tool-pill__svg{position:absolute;width:.75rem;height:.75rem;opacity:0;transform:scale(.6);transition:opacity .2s,transform .2s}.cortex-tool-pill__svg--visible{opacity:1;transform:scale(1)}.cortex-tool-pill__svg--check{color:#059669}.cortex-tool-pill__svg--error{color:#dc2626}.cortex-tool-pill__svg--denied{color:#94a3b8}.cortex-tool-pill__title{font-size:.8125rem;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .3s}.cortex-tool-pill__title--active{color:#4338ca}.cortex-tool-pill__title--complete{color:#047857}.cortex-tool-pill__title--error{color:#dc2626}.cortex-tool-pill__title--denied{color:#94a3b8}.cortex-tool-pill__bar-track{position:absolute;bottom:0;left:0;right:0;height:2px;overflow:hidden}.cortex-tool-pill__bar{height:100%;width:100%;transform-origin:left}.cortex-tool-pill__bar--active{background:#818cf8;animation:cortex-bar-slide 1.5s ease-in-out infinite}.cortex-tool-pill__bar--complete{background:#34d399;animation:cortex-bar-fill .3s ease-out both}.cortex-tool-pill__bar--error{background:#f87171;animation:cortex-bar-fill .3s ease-out both}.cortex-tool-pill__bar--denied{opacity:0}@keyframes cortex-bar-slide{0%{transform:translate(-100%)}to{transform:translate(100%)}}@keyframes cortex-bar-fill{0%{transform:scaleX(0)}to{transform:scaleX(1)}}\n"] }]
|
|
940
1167
|
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], toolCallPart: [{ type: i0.Input, args: [{ isSignal: true, alias: "toolCallPart", required: true }] }] } });
|
|
@@ -982,10 +1209,10 @@ class SubtleActivityComponent {
|
|
|
982
1209
|
if (this.enterTimeout)
|
|
983
1210
|
clearTimeout(this.enterTimeout);
|
|
984
1211
|
}
|
|
985
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
986
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
1212
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SubtleActivityComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1213
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: SubtleActivityComponent, isStandalone: true, selector: "cortex-subtle-activity", inputs: { labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "cortex-subtle-activity" }, ngImport: i0, template: "<div class=\"cortex-subtle-activity__dots\">\n <span class=\"cortex-subtle-activity__dot\"></span>\n <span class=\"cortex-subtle-activity__dot cortex-subtle-activity__dot--d1\"></span>\n <span class=\"cortex-subtle-activity__dot cortex-subtle-activity__dot--d2\"></span>\n</div>\n\n<div class=\"cortex-subtle-activity__label-mask\">\n <span\n class=\"cortex-subtle-activity__label\"\n [class.cortex-subtle-activity__label--idle]=\"labelState() === 'idle'\"\n [class.cortex-subtle-activity__label--exiting]=\"labelState() === 'exiting'\"\n [class.cortex-subtle-activity__label--enter-start]=\"labelState() === 'enter-start'\"\n [class.cortex-subtle-activity__label--entering]=\"labelState() === 'entering'\"\n >\n {{ labels()[currentIndex()] | translate }}\n </span>\n</div>\n", styles: [".cortex-subtle-activity{display:flex;align-items:center;gap:.375rem;padding:.25rem 0;width:fit-content}.cortex-subtle-activity__dots{display:flex;align-items:center;gap:3px}.cortex-subtle-activity__dot{width:3px;height:3px;border-radius:9999px;background:#a5b4fc;animation:cortex-subtle-dot-pulse 1.4s ease-in-out infinite}.cortex-subtle-activity__dot--d1{animation-delay:.2s}.cortex-subtle-activity__dot--d2{animation-delay:.4s}@keyframes cortex-subtle-dot-pulse{0%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1.3)}}.cortex-subtle-activity__label-mask{overflow:hidden;position:relative;height:1.1em}.cortex-subtle-activity__label{display:block;font-size:.75rem;color:#94a3b8;white-space:nowrap;line-height:1.1em}.cortex-subtle-activity__label--idle,.cortex-subtle-activity__label--entering{opacity:1;transform:translateY(0);transition:opacity .3s ease,transform .3s ease}.cortex-subtle-activity__label--exiting{opacity:0;transform:translateY(-6px);transition:opacity .3s ease,transform .3s ease}.cortex-subtle-activity__label--enter-start{opacity:0;transform:translateY(6px);transition:none}\n"], dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
987
1214
|
}
|
|
988
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1215
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SubtleActivityComponent, decorators: [{
|
|
989
1216
|
type: Component,
|
|
990
1217
|
args: [{ selector: 'cortex-subtle-activity', imports: [TranslatePipe], host: { class: 'cortex-subtle-activity' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"cortex-subtle-activity__dots\">\n <span class=\"cortex-subtle-activity__dot\"></span>\n <span class=\"cortex-subtle-activity__dot cortex-subtle-activity__dot--d1\"></span>\n <span class=\"cortex-subtle-activity__dot cortex-subtle-activity__dot--d2\"></span>\n</div>\n\n<div class=\"cortex-subtle-activity__label-mask\">\n <span\n class=\"cortex-subtle-activity__label\"\n [class.cortex-subtle-activity__label--idle]=\"labelState() === 'idle'\"\n [class.cortex-subtle-activity__label--exiting]=\"labelState() === 'exiting'\"\n [class.cortex-subtle-activity__label--enter-start]=\"labelState() === 'enter-start'\"\n [class.cortex-subtle-activity__label--entering]=\"labelState() === 'entering'\"\n >\n {{ labels()[currentIndex()] | translate }}\n </span>\n</div>\n", styles: [".cortex-subtle-activity{display:flex;align-items:center;gap:.375rem;padding:.25rem 0;width:fit-content}.cortex-subtle-activity__dots{display:flex;align-items:center;gap:3px}.cortex-subtle-activity__dot{width:3px;height:3px;border-radius:9999px;background:#a5b4fc;animation:cortex-subtle-dot-pulse 1.4s ease-in-out infinite}.cortex-subtle-activity__dot--d1{animation-delay:.2s}.cortex-subtle-activity__dot--d2{animation-delay:.4s}@keyframes cortex-subtle-dot-pulse{0%,to{opacity:.3;transform:scale(.8)}40%{opacity:1;transform:scale(1.3)}}.cortex-subtle-activity__label-mask{overflow:hidden;position:relative;height:1.1em}.cortex-subtle-activity__label{display:block;font-size:.75rem;color:#94a3b8;white-space:nowrap;line-height:1.1em}.cortex-subtle-activity__label--idle,.cortex-subtle-activity__label--entering{opacity:1;transform:translateY(0);transition:opacity .3s ease,transform .3s ease}.cortex-subtle-activity__label--exiting{opacity:0;transform:translateY(-6px);transition:opacity .3s ease,transform .3s ease}.cortex-subtle-activity__label--enter-start{opacity:0;transform:translateY(6px);transition:none}\n"] }]
|
|
991
1218
|
}], ctorParameters: () => [], propDecorators: { labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: true }] }] } });
|
|
@@ -1005,10 +1232,10 @@ const LABELS$3 = [
|
|
|
1005
1232
|
class MessageReasoningAnimatedComponent {
|
|
1006
1233
|
reasoningPart = input.required(...(ngDevMode ? [{ debugName: "reasoningPart" }] : /* istanbul ignore next */ []));
|
|
1007
1234
|
labels = LABELS$3;
|
|
1008
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1009
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
1235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageReasoningAnimatedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1236
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: MessageReasoningAnimatedComponent, isStandalone: true, selector: "cortex-message-reasoning-animated", inputs: { reasoningPart: { classPropertyName: "reasoningPart", publicName: "reasoningPart", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "cortex-reasoning-animated" }, ngImport: i0, template: "<cortex-subtle-activity [labels]=\"labels\" />\n", styles: [".cortex-reasoning-animated{display:block}\n"], dependencies: [{ kind: "component", type: SubtleActivityComponent, selector: "cortex-subtle-activity", inputs: ["labels"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1010
1237
|
}
|
|
1011
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageReasoningAnimatedComponent, decorators: [{
|
|
1012
1239
|
type: Component,
|
|
1013
1240
|
args: [{ selector: 'cortex-message-reasoning-animated', imports: [SubtleActivityComponent], host: { class: 'cortex-reasoning-animated' }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<cortex-subtle-activity [labels]=\"labels\" />\n", styles: [".cortex-reasoning-animated{display:block}\n"] }]
|
|
1014
1241
|
}], propDecorators: { reasoningPart: [{ type: i0.Input, args: [{ isSignal: true, alias: "reasoningPart", required: true }] }] } });
|
|
@@ -1027,10 +1254,10 @@ const LABELS$2 = [
|
|
|
1027
1254
|
];
|
|
1028
1255
|
class ToolCallEndpointAnimatedComponent {
|
|
1029
1256
|
labels = LABELS$2;
|
|
1030
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1031
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
1257
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ToolCallEndpointAnimatedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1258
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: ToolCallEndpointAnimatedComponent, isStandalone: true, selector: "cortex-tool-call-endpoint-animated", ngImport: i0, template: '<cortex-subtle-activity [labels]="labels" />', isInline: true, dependencies: [{ kind: "component", type: SubtleActivityComponent, selector: "cortex-subtle-activity", inputs: ["labels"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1032
1259
|
}
|
|
1033
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ToolCallEndpointAnimatedComponent, decorators: [{
|
|
1034
1261
|
type: Component,
|
|
1035
1262
|
args: [{
|
|
1036
1263
|
selector: 'cortex-tool-call-endpoint-animated',
|
|
@@ -1055,10 +1282,10 @@ const LABELS$1 = [
|
|
|
1055
1282
|
];
|
|
1056
1283
|
class ToolQueryGraphAnimatedComponent {
|
|
1057
1284
|
labels = LABELS$1;
|
|
1058
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1059
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
1285
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ToolQueryGraphAnimatedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1286
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: ToolQueryGraphAnimatedComponent, isStandalone: true, selector: "cortex-tool-query-graph-animated", ngImport: i0, template: '<cortex-subtle-activity [labels]="labels" />', isInline: true, dependencies: [{ kind: "component", type: SubtleActivityComponent, selector: "cortex-subtle-activity", inputs: ["labels"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1060
1287
|
}
|
|
1061
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1288
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ToolQueryGraphAnimatedComponent, decorators: [{
|
|
1062
1289
|
type: Component,
|
|
1063
1290
|
args: [{
|
|
1064
1291
|
selector: 'cortex-tool-query-graph-animated',
|
|
@@ -1083,10 +1310,10 @@ const LABELS = [
|
|
|
1083
1310
|
];
|
|
1084
1311
|
class ToolExecuteCodeAnimatedComponent {
|
|
1085
1312
|
labels = LABELS;
|
|
1086
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1087
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
1313
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ToolExecuteCodeAnimatedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1314
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: ToolExecuteCodeAnimatedComponent, isStandalone: true, selector: "cortex-tool-execute-code-animated", ngImport: i0, template: '<cortex-subtle-activity [labels]="labels" />', isInline: true, dependencies: [{ kind: "component", type: SubtleActivityComponent, selector: "cortex-subtle-activity", inputs: ["labels"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1088
1315
|
}
|
|
1089
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1316
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ToolExecuteCodeAnimatedComponent, decorators: [{
|
|
1090
1317
|
type: Component,
|
|
1091
1318
|
args: [{
|
|
1092
1319
|
selector: 'cortex-tool-execute-code-animated',
|
|
@@ -1103,10 +1330,10 @@ class MessagePartComponent {
|
|
|
1103
1330
|
debugMode = input(false, ...(ngDevMode ? [{ debugName: "debugMode" }] : /* istanbul ignore next */ []));
|
|
1104
1331
|
animate = input(false, ...(ngDevMode ? [{ debugName: "animate" }] : /* istanbul ignore next */ []));
|
|
1105
1332
|
isStaticToolUIPart = isStaticToolUIPart;
|
|
1106
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1107
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1333
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessagePartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1334
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessagePartComponent, isStandalone: true, selector: "cortex-message-part", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, part: { classPropertyName: "part", publicName: "part", isSignal: true, isRequired: true, transformFunction: null }, debugMode: { classPropertyName: "debugMode", publicName: "debugMode", isSignal: true, isRequired: false, transformFunction: null }, animate: { classPropertyName: "animate", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.cortex-message-part--animated": "animate()" }, classAttribute: "cortex-message-part" }, ngImport: i0, template: "@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()) {\n <cortex-message-tool-call-part [toolCallPart]=\"myPart\" />\n } @else {\n @switch (myPart.type) {\n @case ('tool-callEndpoint') {\n <cortex-tool-call-endpoint-animated />\n }\n @case ('tool-queryGraph') {\n <cortex-tool-query-graph-animated />\n }\n @case ('tool-executeCode') {\n <cortex-tool-execute-code-animated />\n }\n @default {\n <cortex-message-tool-call-animated [toolCallPart]=\"myPart\" [message]=\"message()\" />\n }\n }\n }\n } @else {\n <p class=\"cortex-unhandled-type\">Unhandled type: {{ part().type }}</p>\n }\n }\n}\n", styles: [".cortex-message-part{display:block}.cortex-message-part:empty{display:none}.cortex-message-part--animated{animation:cortex-part-fade-in-up .2s cubic-bezier(.34,1.56,.64,1) both}@keyframes cortex-part-fade-in-up{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}.cortex-unhandled-type{text-align:center;font-size:.75rem;color:#94a3b8}\n"], dependencies: [{ kind: "component", type: MessageTextPartComponent, selector: "cortex-message-text-part", inputs: ["role", "textPart"] }, { kind: "component", type: MessageReasoningPartComponent, selector: "cortex-message-reasoning-part", inputs: ["reasoningPart"] }, { kind: "component", type: MessageToolCallPartComponent, selector: "cortex-message-tool-call-part", inputs: ["toolCallPart"] }, { kind: "component", type: MessageToolCallAnimatedComponent, selector: "cortex-message-tool-call-animated", inputs: ["message", "toolCallPart"] }, { kind: "component", type: MessageReasoningAnimatedComponent, selector: "cortex-message-reasoning-animated", inputs: ["reasoningPart"] }, { kind: "component", type: ToolCallEndpointAnimatedComponent, selector: "cortex-tool-call-endpoint-animated" }, { kind: "component", type: ToolQueryGraphAnimatedComponent, selector: "cortex-tool-query-graph-animated" }, { kind: "component", type: ToolExecuteCodeAnimatedComponent, selector: "cortex-tool-execute-code-animated" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1108
1335
|
}
|
|
1109
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1336
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessagePartComponent, decorators: [{
|
|
1110
1337
|
type: Component,
|
|
1111
1338
|
args: [{ selector: 'cortex-message-part', imports: [
|
|
1112
1339
|
MessageTextPartComponent,
|
|
@@ -1123,6 +1350,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
1123
1350
|
}, template: "@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()) {\n <cortex-message-tool-call-part [toolCallPart]=\"myPart\" />\n } @else {\n @switch (myPart.type) {\n @case ('tool-callEndpoint') {\n <cortex-tool-call-endpoint-animated />\n }\n @case ('tool-queryGraph') {\n <cortex-tool-query-graph-animated />\n }\n @case ('tool-executeCode') {\n <cortex-tool-execute-code-animated />\n }\n @default {\n <cortex-message-tool-call-animated [toolCallPart]=\"myPart\" [message]=\"message()\" />\n }\n }\n }\n } @else {\n <p class=\"cortex-unhandled-type\">Unhandled type: {{ part().type }}</p>\n }\n }\n}\n", styles: [".cortex-message-part{display:block}.cortex-message-part:empty{display:none}.cortex-message-part--animated{animation:cortex-part-fade-in-up .2s cubic-bezier(.34,1.56,.64,1) both}@keyframes cortex-part-fade-in-up{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}.cortex-unhandled-type{text-align:center;font-size:.75rem;color:#94a3b8}\n"] }]
|
|
1124
1351
|
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], part: [{ type: i0.Input, args: [{ isSignal: true, alias: "part", required: true }] }], debugMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "debugMode", required: false }] }], animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }] } });
|
|
1125
1352
|
|
|
1353
|
+
class MessageTokenUsageComponent {
|
|
1354
|
+
usage = input.required(...(ngDevMode ? [{ debugName: "usage" }] : /* istanbul ignore next */ []));
|
|
1355
|
+
modelId = input(...(ngDevMode ? [undefined, { debugName: "modelId" }] : /* istanbul ignore next */ []));
|
|
1356
|
+
expanded = signal(false, ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
1357
|
+
cacheRatio = computed(() => {
|
|
1358
|
+
const u = this.usage();
|
|
1359
|
+
if (u.input.total === 0)
|
|
1360
|
+
return 0;
|
|
1361
|
+
return Math.round((u.input.cacheRead / u.input.total) * 100);
|
|
1362
|
+
}, ...(ngDevMode ? [{ debugName: "cacheRatio" }] : /* istanbul ignore next */ []));
|
|
1363
|
+
toggle() {
|
|
1364
|
+
this.expanded.update((v) => !v);
|
|
1365
|
+
}
|
|
1366
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageTokenUsageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1367
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageTokenUsageComponent, isStandalone: true, selector: "cortex-message-token-usage", inputs: { usage: { classPropertyName: "usage", publicName: "usage", isSignal: true, isRequired: true, transformFunction: null }, modelId: { classPropertyName: "modelId", publicName: "modelId", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.cortex-token-usage--expanded": "expanded()" }, classAttribute: "cortex-token-usage" }, ngImport: i0, template: "<button class=\"cortex-token-usage__summary\" (click)=\"toggle()\">\n <span class=\"cortex-token-usage__total\">\n <span class=\"cortex-token-usage__total-number\">{{ usage().total | number }}</span>\n <span class=\"cortex-token-usage__total-label\">tokens</span>\n </span>\n\n @if (modelId(); as id) {\n <span class=\"cortex-token-usage__model\">{{ id }}</span>\n }\n\n <span class=\"cortex-token-usage__pills\">\n <span class=\"cortex-token-usage__pill\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--input\"></span>\n {{ usage().input.total | number }}\n </span>\n <span class=\"cortex-token-usage__pill\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--output\"></span>\n {{ usage().output.total | number }}\n </span>\n </span>\n\n <svg class=\"cortex-token-usage__chevron\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path\n d=\"M3 4.5L6 7.5L9 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</button>\n\n<div class=\"cortex-token-usage__details\">\n <div class=\"cortex-token-usage__details-inner\">\n <div class=\"cortex-token-usage__section\">\n <div class=\"cortex-token-usage__section-header\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--input\"></span>\n <span class=\"cortex-token-usage__section-label\">Input</span>\n <span class=\"cortex-token-usage__section-total\">{{ usage().input.total | number }}</span>\n </div>\n <div class=\"cortex-token-usage__rows\">\n @if (usage().input.noCache) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Fresh</span>\n <span class=\"cortex-token-usage__row-value\">{{ usage().input.noCache | number }}</span>\n </div>\n }\n @if (usage().input.cacheRead) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Cache read</span>\n <span class=\"cortex-token-usage__row-value\">{{\n usage().input.cacheRead | number\n }}</span>\n </div>\n }\n @if (usage().input.cacheWrite) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Cache write</span>\n <span class=\"cortex-token-usage__row-value\">{{\n usage().input.cacheWrite | number\n }}</span>\n </div>\n }\n @if (cacheRatio() > 0) {\n <div class=\"cortex-token-usage__row cortex-token-usage__row--highlight\">\n <span class=\"cortex-token-usage__row-label\">Cache hit</span>\n <span class=\"cortex-token-usage__row-value\">{{ cacheRatio() }}%</span>\n </div>\n }\n </div>\n </div>\n\n <div class=\"cortex-token-usage__divider\"></div>\n\n <div class=\"cortex-token-usage__section\">\n <div class=\"cortex-token-usage__section-header\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--output\"></span>\n <span class=\"cortex-token-usage__section-label\">Output</span>\n <span class=\"cortex-token-usage__section-total\">{{ usage().output.total | number }}</span>\n </div>\n <div class=\"cortex-token-usage__rows\">\n @if (usage().output.text) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Text</span>\n <span class=\"cortex-token-usage__row-value\">{{ usage().output.text | number }}</span>\n </div>\n }\n @if (usage().output.reasoning) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Reasoning</span>\n <span class=\"cortex-token-usage__row-value\">{{\n usage().output.reasoning | number\n }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [".cortex-token-usage{direction:ltr;display:flex;flex-direction:column;margin-top:.25rem;font-family:SF Mono,Cascadia Code,Fira Code,JetBrains Mono,ui-monospace,monospace;font-size:.6875rem;line-height:1.4;color:#94a3b8;-webkit-user-select:none;user-select:none}html[dir=rtl] .cortex-token-usage__summary{align-self:end}html[dir=ltr] .cortex-token-usage__summary{align-self:start}.cortex-token-usage__summary{display:inline-flex;align-items:center;gap:.625rem;padding:.25rem .5rem;border:1px solid transparent;border-radius:6px;background:transparent;cursor:pointer;transition:background .2s ease,border-color .2s ease;font:inherit;color:inherit;letter-spacing:.01em}.cortex-token-usage__summary:hover{background:#f8fafc;border-color:#e2e8f0}.cortex-token-usage__total-number{font-weight:600;font-variant-numeric:tabular-nums;color:#64748b}.cortex-token-usage__total-label{margin-inline-start:.1875rem;color:#94a3b8;font-weight:400;letter-spacing:.04em;text-transform:lowercase}.cortex-token-usage__model{color:#94a3b8;font-weight:400;font-size:.625rem;letter-spacing:.02em}.cortex-token-usage__pills{display:inline-flex;align-items:center;gap:.375rem}.cortex-token-usage__pill{display:inline-flex;align-items:center;gap:.25rem;font-variant-numeric:tabular-nums;color:#94a3b8}.cortex-token-usage__dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}.cortex-token-usage__dot--input{background:#f59e0b;box-shadow:0 0 0 1px #f59e0b33}.cortex-token-usage__dot--output{background:#6366f1;box-shadow:0 0 0 1px #6366f133}.cortex-token-usage__chevron{color:#cbd5e1;transition:transform .25s cubic-bezier(.4,0,.2,1);flex-shrink:0}.cortex-token-usage--expanded .cortex-token-usage__chevron{transform:rotate(180deg)}.cortex-token-usage__details{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s cubic-bezier(.4,0,.2,1),opacity .2s ease,margin .2s ease;opacity:0;margin-top:0;margin-inline-start:.5rem;padding-inline-start:.625rem;border-inline-start:1px solid transparent}.cortex-token-usage__details-inner{overflow:hidden}.cortex-token-usage--expanded .cortex-token-usage__details{grid-template-rows:1fr;opacity:1;margin-top:.25rem;border-inline-start-color:#e2e8f0}.cortex-token-usage__section{padding:.375rem 0}.cortex-token-usage__section-header{display:flex;align-items:center;gap:.375rem;margin-bottom:.25rem}.cortex-token-usage__section-label{font-weight:500;color:#64748b;letter-spacing:.03em;text-transform:uppercase;font-size:.625rem}.cortex-token-usage__section-total{margin-inline-start:auto;font-weight:600;font-variant-numeric:tabular-nums;color:#64748b}.cortex-token-usage__rows{display:flex;flex-direction:column;gap:.125rem}.cortex-token-usage__row{display:flex;align-items:baseline;justify-content:space-between;padding:.0625rem 0;padding-inline-start:calc(5px + .375rem)}.cortex-token-usage__row-label{color:#94a3b8}.cortex-token-usage__row-value{font-variant-numeric:tabular-nums;color:#64748b;font-weight:500}.cortex-token-usage__row--highlight .cortex-token-usage__row-value{color:#10b981;font-weight:600}.cortex-token-usage__divider{height:1px;background:#f1f5f9}\n"], dependencies: [{ kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1368
|
+
}
|
|
1369
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageTokenUsageComponent, decorators: [{
|
|
1370
|
+
type: Component,
|
|
1371
|
+
args: [{ selector: 'cortex-message-token-usage', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [DecimalPipe], host: { class: 'cortex-token-usage', '[class.cortex-token-usage--expanded]': 'expanded()' }, template: "<button class=\"cortex-token-usage__summary\" (click)=\"toggle()\">\n <span class=\"cortex-token-usage__total\">\n <span class=\"cortex-token-usage__total-number\">{{ usage().total | number }}</span>\n <span class=\"cortex-token-usage__total-label\">tokens</span>\n </span>\n\n @if (modelId(); as id) {\n <span class=\"cortex-token-usage__model\">{{ id }}</span>\n }\n\n <span class=\"cortex-token-usage__pills\">\n <span class=\"cortex-token-usage__pill\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--input\"></span>\n {{ usage().input.total | number }}\n </span>\n <span class=\"cortex-token-usage__pill\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--output\"></span>\n {{ usage().output.total | number }}\n </span>\n </span>\n\n <svg class=\"cortex-token-usage__chevron\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path\n d=\"M3 4.5L6 7.5L9 4.5\"\n stroke=\"currentColor\"\n stroke-width=\"1.25\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n</button>\n\n<div class=\"cortex-token-usage__details\">\n <div class=\"cortex-token-usage__details-inner\">\n <div class=\"cortex-token-usage__section\">\n <div class=\"cortex-token-usage__section-header\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--input\"></span>\n <span class=\"cortex-token-usage__section-label\">Input</span>\n <span class=\"cortex-token-usage__section-total\">{{ usage().input.total | number }}</span>\n </div>\n <div class=\"cortex-token-usage__rows\">\n @if (usage().input.noCache) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Fresh</span>\n <span class=\"cortex-token-usage__row-value\">{{ usage().input.noCache | number }}</span>\n </div>\n }\n @if (usage().input.cacheRead) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Cache read</span>\n <span class=\"cortex-token-usage__row-value\">{{\n usage().input.cacheRead | number\n }}</span>\n </div>\n }\n @if (usage().input.cacheWrite) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Cache write</span>\n <span class=\"cortex-token-usage__row-value\">{{\n usage().input.cacheWrite | number\n }}</span>\n </div>\n }\n @if (cacheRatio() > 0) {\n <div class=\"cortex-token-usage__row cortex-token-usage__row--highlight\">\n <span class=\"cortex-token-usage__row-label\">Cache hit</span>\n <span class=\"cortex-token-usage__row-value\">{{ cacheRatio() }}%</span>\n </div>\n }\n </div>\n </div>\n\n <div class=\"cortex-token-usage__divider\"></div>\n\n <div class=\"cortex-token-usage__section\">\n <div class=\"cortex-token-usage__section-header\">\n <span class=\"cortex-token-usage__dot cortex-token-usage__dot--output\"></span>\n <span class=\"cortex-token-usage__section-label\">Output</span>\n <span class=\"cortex-token-usage__section-total\">{{ usage().output.total | number }}</span>\n </div>\n <div class=\"cortex-token-usage__rows\">\n @if (usage().output.text) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Text</span>\n <span class=\"cortex-token-usage__row-value\">{{ usage().output.text | number }}</span>\n </div>\n }\n @if (usage().output.reasoning) {\n <div class=\"cortex-token-usage__row\">\n <span class=\"cortex-token-usage__row-label\">Reasoning</span>\n <span class=\"cortex-token-usage__row-value\">{{\n usage().output.reasoning | number\n }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n</div>\n", styles: [".cortex-token-usage{direction:ltr;display:flex;flex-direction:column;margin-top:.25rem;font-family:SF Mono,Cascadia Code,Fira Code,JetBrains Mono,ui-monospace,monospace;font-size:.6875rem;line-height:1.4;color:#94a3b8;-webkit-user-select:none;user-select:none}html[dir=rtl] .cortex-token-usage__summary{align-self:end}html[dir=ltr] .cortex-token-usage__summary{align-self:start}.cortex-token-usage__summary{display:inline-flex;align-items:center;gap:.625rem;padding:.25rem .5rem;border:1px solid transparent;border-radius:6px;background:transparent;cursor:pointer;transition:background .2s ease,border-color .2s ease;font:inherit;color:inherit;letter-spacing:.01em}.cortex-token-usage__summary:hover{background:#f8fafc;border-color:#e2e8f0}.cortex-token-usage__total-number{font-weight:600;font-variant-numeric:tabular-nums;color:#64748b}.cortex-token-usage__total-label{margin-inline-start:.1875rem;color:#94a3b8;font-weight:400;letter-spacing:.04em;text-transform:lowercase}.cortex-token-usage__model{color:#94a3b8;font-weight:400;font-size:.625rem;letter-spacing:.02em}.cortex-token-usage__pills{display:inline-flex;align-items:center;gap:.375rem}.cortex-token-usage__pill{display:inline-flex;align-items:center;gap:.25rem;font-variant-numeric:tabular-nums;color:#94a3b8}.cortex-token-usage__dot{width:5px;height:5px;border-radius:50%;flex-shrink:0}.cortex-token-usage__dot--input{background:#f59e0b;box-shadow:0 0 0 1px #f59e0b33}.cortex-token-usage__dot--output{background:#6366f1;box-shadow:0 0 0 1px #6366f133}.cortex-token-usage__chevron{color:#cbd5e1;transition:transform .25s cubic-bezier(.4,0,.2,1);flex-shrink:0}.cortex-token-usage--expanded .cortex-token-usage__chevron{transform:rotate(180deg)}.cortex-token-usage__details{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s cubic-bezier(.4,0,.2,1),opacity .2s ease,margin .2s ease;opacity:0;margin-top:0;margin-inline-start:.5rem;padding-inline-start:.625rem;border-inline-start:1px solid transparent}.cortex-token-usage__details-inner{overflow:hidden}.cortex-token-usage--expanded .cortex-token-usage__details{grid-template-rows:1fr;opacity:1;margin-top:.25rem;border-inline-start-color:#e2e8f0}.cortex-token-usage__section{padding:.375rem 0}.cortex-token-usage__section-header{display:flex;align-items:center;gap:.375rem;margin-bottom:.25rem}.cortex-token-usage__section-label{font-weight:500;color:#64748b;letter-spacing:.03em;text-transform:uppercase;font-size:.625rem}.cortex-token-usage__section-total{margin-inline-start:auto;font-weight:600;font-variant-numeric:tabular-nums;color:#64748b}.cortex-token-usage__rows{display:flex;flex-direction:column;gap:.125rem}.cortex-token-usage__row{display:flex;align-items:baseline;justify-content:space-between;padding:.0625rem 0;padding-inline-start:calc(5px + .375rem)}.cortex-token-usage__row-label{color:#94a3b8}.cortex-token-usage__row-value{font-variant-numeric:tabular-nums;color:#64748b;font-weight:500}.cortex-token-usage__row--highlight .cortex-token-usage__row-value{color:#10b981;font-weight:600}.cortex-token-usage__divider{height:1px;background:#f1f5f9}\n"] }]
|
|
1372
|
+
}], propDecorators: { usage: [{ type: i0.Input, args: [{ isSignal: true, alias: "usage", required: true }] }], modelId: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelId", required: false }] }] } });
|
|
1373
|
+
|
|
1126
1374
|
class MessageComponent {
|
|
1127
1375
|
message = input.required(...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
1128
1376
|
debugMode = input(false, ...(ngDevMode ? [{ debugName: "debugMode" }] : /* istanbul ignore next */ []));
|
|
@@ -1138,31 +1386,59 @@ class MessageComponent {
|
|
|
1138
1386
|
constructor() {
|
|
1139
1387
|
effect(() => {
|
|
1140
1388
|
const parts = this.message().parts;
|
|
1141
|
-
this.parts.set(parts);
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1389
|
+
this.parts.set(parts.map((part) => this.trackPart(part)));
|
|
1390
|
+
this.wrapPush(parts);
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
trackPart(part) {
|
|
1394
|
+
const trackedPart = part;
|
|
1395
|
+
if (trackedPart.__cortexTracked) {
|
|
1396
|
+
return trackedPart;
|
|
1397
|
+
}
|
|
1398
|
+
trackedPart.__id = trackedPart.__id ?? generateId();
|
|
1399
|
+
Object.defineProperty(trackedPart, '__cortexTracked', {
|
|
1400
|
+
value: true,
|
|
1401
|
+
configurable: true,
|
|
1402
|
+
});
|
|
1403
|
+
Object.keys(trackedPart).forEach((prop) => {
|
|
1404
|
+
if (prop === '__id') {
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1407
|
+
const descriptor = Object.getOwnPropertyDescriptor(trackedPart, prop);
|
|
1408
|
+
if (!descriptor?.configurable || descriptor.get || descriptor.set) {
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
let value = trackedPart[prop];
|
|
1412
|
+
Object.defineProperty(trackedPart, prop, {
|
|
1413
|
+
get: () => value,
|
|
1414
|
+
set: (newValue) => {
|
|
1415
|
+
value = newValue;
|
|
1416
|
+
this.parts.update((existingParts) => {
|
|
1417
|
+
return existingParts.map((existingPart) => {
|
|
1418
|
+
return existingPart.__id === trackedPart.__id
|
|
1419
|
+
? { ...existingPart, [prop]: newValue }
|
|
1420
|
+
: existingPart;
|
|
1161
1421
|
});
|
|
1162
1422
|
});
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
|
-
};
|
|
1423
|
+
},
|
|
1424
|
+
configurable: true,
|
|
1425
|
+
});
|
|
1426
|
+
});
|
|
1427
|
+
return trackedPart;
|
|
1428
|
+
}
|
|
1429
|
+
wrapPush(parts) {
|
|
1430
|
+
if (parts.__cortexPushWrapped) {
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
const originalPush = parts.push;
|
|
1434
|
+
parts.push = (...items) => {
|
|
1435
|
+
const newParts = items.map((part) => this.trackPart(part));
|
|
1436
|
+
this.parts.update((existingParts) => [...existingParts, ...newParts]);
|
|
1437
|
+
return originalPush.apply(parts, newParts);
|
|
1438
|
+
};
|
|
1439
|
+
Object.defineProperty(parts, '__cortexPushWrapped', {
|
|
1440
|
+
value: true,
|
|
1441
|
+
configurable: true,
|
|
1166
1442
|
});
|
|
1167
1443
|
}
|
|
1168
1444
|
isHiddenInAnimatedMode(part) {
|
|
@@ -1176,12 +1452,17 @@ class MessageComponent {
|
|
|
1176
1452
|
}
|
|
1177
1453
|
return false;
|
|
1178
1454
|
}
|
|
1179
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1180
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1455
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1456
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageComponent, isStandalone: true, selector: "cortex-message", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, debugMode: { classPropertyName: "debugMode", publicName: "debugMode", isSignal: true, isRequired: false, transformFunction: null }, animate: { classPropertyName: "animate", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "cortex-message" }, ngImport: i0, template: "@if (visibleParts().length) {\n <div class=\"cortex-message-parts\">\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\n @if (message().metadata?.isAborted) {\n <cortex-message-aborted-flag />\n }\n\n @if (debugMode() && message().metadata?.tokenUsage; as usage) {\n <cortex-message-token-usage [usage]=\"usage\" [modelId]=\"message().metadata?.modelId\" />\n }\n </div>\n}\n", styles: [".cortex-message:empty{display:none}.cortex-message-parts{width:100%;display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "component", type: MessageAbortedFlagComponent, selector: "cortex-message-aborted-flag" }, { kind: "component", type: MessagePartComponent, selector: "cortex-message-part", inputs: ["message", "part", "debugMode", "animate"] }, { kind: "component", type: MessageTokenUsageComponent, selector: "cortex-message-token-usage", inputs: ["usage", "modelId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1181
1457
|
}
|
|
1182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1458
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageComponent, decorators: [{
|
|
1183
1459
|
type: Component,
|
|
1184
|
-
args: [{ selector: 'cortex-message', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
1460
|
+
args: [{ selector: 'cortex-message', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
1461
|
+
MessageAbortedFlagComponent,
|
|
1462
|
+
MessagePartComponent,
|
|
1463
|
+
MessageTokenUsageComponent,
|
|
1464
|
+
JsonPipe,
|
|
1465
|
+
], host: { class: 'cortex-message' }, template: "@if (visibleParts().length) {\n <div class=\"cortex-message-parts\">\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\n @if (message().metadata?.isAborted) {\n <cortex-message-aborted-flag />\n }\n\n @if (debugMode() && message().metadata?.tokenUsage; as usage) {\n <cortex-message-token-usage [usage]=\"usage\" [modelId]=\"message().metadata?.modelId\" />\n }\n </div>\n}\n", styles: [".cortex-message:empty{display:none}.cortex-message-parts{width:100%;display:flex;flex-direction:column;gap:.5rem}\n"] }]
|
|
1185
1466
|
}], ctorParameters: () => [], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], debugMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "debugMode", required: false }] }], animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }] } });
|
|
1186
1467
|
|
|
1187
1468
|
class MessageListComponent {
|
|
@@ -1190,6 +1471,8 @@ class MessageListComponent {
|
|
|
1190
1471
|
messagesContainer = viewChild('messagesContainer', ...(ngDevMode ? [{ debugName: "messagesContainer" }] : /* istanbul ignore next */ []));
|
|
1191
1472
|
shouldScrollToBottom = true;
|
|
1192
1473
|
isNearBottom = true;
|
|
1474
|
+
mutationObserver = undefined;
|
|
1475
|
+
scrollToBottomQueued = false;
|
|
1193
1476
|
animateNewParts = signal(false, ...(ngDevMode ? [{ debugName: "animateNewParts" }] : /* istanbul ignore next */ []));
|
|
1194
1477
|
constructor(chatService, destroyRef) {
|
|
1195
1478
|
this.chatService = chatService;
|
|
@@ -1199,10 +1482,7 @@ class MessageListComponent {
|
|
|
1199
1482
|
if (!this.shouldScrollToBottom && !this.isNearBottom) {
|
|
1200
1483
|
return;
|
|
1201
1484
|
}
|
|
1202
|
-
|
|
1203
|
-
this.scrollToBottom();
|
|
1204
|
-
this.shouldScrollToBottom = false;
|
|
1205
|
-
});
|
|
1485
|
+
this.scheduleScrollToBottom();
|
|
1206
1486
|
});
|
|
1207
1487
|
chatService.events$.pipe(takeUntilDestroyed(destroyRef)).subscribe((event) => {
|
|
1208
1488
|
if (event === 'onThreadSelected') {
|
|
@@ -1213,13 +1493,14 @@ class MessageListComponent {
|
|
|
1213
1493
|
if (event === 'onSend')
|
|
1214
1494
|
this.shouldScrollToBottom = true;
|
|
1215
1495
|
});
|
|
1496
|
+
destroyRef.onDestroy(() => {
|
|
1497
|
+
this.mutationObserver?.disconnect();
|
|
1498
|
+
});
|
|
1216
1499
|
}
|
|
1217
1500
|
ngAfterViewInit() {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
this.animateNewParts.set(true);
|
|
1222
|
-
});
|
|
1501
|
+
this.observeMessageMutations();
|
|
1502
|
+
this.scheduleScrollToBottom();
|
|
1503
|
+
queueMicrotask(() => this.animateNewParts.set(true));
|
|
1223
1504
|
}
|
|
1224
1505
|
onScroll() {
|
|
1225
1506
|
const el = this.messagesContainer()?.nativeElement;
|
|
@@ -1233,10 +1514,38 @@ class MessageListComponent {
|
|
|
1233
1514
|
el.scrollTop = el.scrollHeight;
|
|
1234
1515
|
}
|
|
1235
1516
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1517
|
+
scheduleScrollToBottom() {
|
|
1518
|
+
if (this.scrollToBottomQueued) {
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
this.scrollToBottomQueued = true;
|
|
1522
|
+
queueMicrotask(() => {
|
|
1523
|
+
this.scrollToBottomQueued = false;
|
|
1524
|
+
this.scrollToBottom();
|
|
1525
|
+
this.shouldScrollToBottom = false;
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
observeMessageMutations() {
|
|
1529
|
+
const el = this.messagesContainer()?.nativeElement;
|
|
1530
|
+
if (!el || typeof MutationObserver === 'undefined') {
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
this.mutationObserver = new MutationObserver(() => {
|
|
1534
|
+
if (!this.shouldScrollToBottom && !this.isNearBottom) {
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1537
|
+
this.scheduleScrollToBottom();
|
|
1538
|
+
});
|
|
1539
|
+
this.mutationObserver.observe(el, {
|
|
1540
|
+
childList: true,
|
|
1541
|
+
subtree: true,
|
|
1542
|
+
characterData: true,
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageListComponent, deps: [{ token: CortexChatService }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1546
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessageListComponent, isStandalone: true, selector: "cortex-message-list", inputs: { debugMode: { classPropertyName: "debugMode", publicName: "debugMode", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "messagesContainer", first: true, predicate: ["messagesContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"cortex-message-list\" #messagesContainer (scroll)=\"onScroll()\">\n @for (message of chatService.chat()?.messages; track message.id) {\n <cortex-message [message]=\"message\" [debugMode]=\"debugMode()\" [animate]=\"animateNewParts()\" />\n }\n</div>\n", styles: [".cortex-message-list{height:100%;overflow-y:auto;width:100%;display:flex;flex-direction:column;gap:.5rem;padding:1rem}\n"], dependencies: [{ kind: "component", type: MessageComponent, selector: "cortex-message", inputs: ["message", "debugMode", "animate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1238
1547
|
}
|
|
1239
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1548
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessageListComponent, decorators: [{
|
|
1240
1549
|
type: Component,
|
|
1241
1550
|
args: [{ selector: 'cortex-message-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [MessageComponent], template: "<div class=\"cortex-message-list\" #messagesContainer (scroll)=\"onScroll()\">\n @for (message of chatService.chat()?.messages; track message.id) {\n <cortex-message [message]=\"message\" [debugMode]=\"debugMode()\" [animate]=\"animateNewParts()\" />\n }\n</div>\n", styles: [".cortex-message-list{height:100%;overflow-y:auto;width:100%;display:flex;flex-direction:column;gap:.5rem;padding:1rem}\n"] }]
|
|
1242
1551
|
}], ctorParameters: () => [{ type: CortexChatService }, { type: i0.DestroyRef }], propDecorators: { debugMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "debugMode", required: false }] }], messagesContainer: [{ type: i0.ViewChild, args: ['messagesContainer', { isSignal: true }] }] } });
|
|
@@ -1327,6 +1636,8 @@ var translate_reasoning_6$1 = "Mulling it over...";
|
|
|
1327
1636
|
var translate_reasoning_7$1 = "Finding the best approach...";
|
|
1328
1637
|
var translate_reasoning_8$1 = "Organizing my thoughts...";
|
|
1329
1638
|
var translate_reasoning_9$1 = "Almost there...";
|
|
1639
|
+
var translate_running$1 = "Running";
|
|
1640
|
+
var translate_aborted$1 = "Aborted";
|
|
1330
1641
|
var en = {
|
|
1331
1642
|
translate_new: translate_new$1,
|
|
1332
1643
|
translate_threads: translate_threads$1,
|
|
@@ -1413,7 +1724,9 @@ var en = {
|
|
|
1413
1724
|
translate_reasoning_6: translate_reasoning_6$1,
|
|
1414
1725
|
translate_reasoning_7: translate_reasoning_7$1,
|
|
1415
1726
|
translate_reasoning_8: translate_reasoning_8$1,
|
|
1416
|
-
translate_reasoning_9: translate_reasoning_9$1
|
|
1727
|
+
translate_reasoning_9: translate_reasoning_9$1,
|
|
1728
|
+
translate_running: translate_running$1,
|
|
1729
|
+
translate_aborted: translate_aborted$1
|
|
1417
1730
|
};
|
|
1418
1731
|
|
|
1419
1732
|
var translate_new = "جديد";
|
|
@@ -1502,6 +1815,8 @@ var translate_reasoning_6 = "جارٍ التمعن في الأمر...";
|
|
|
1502
1815
|
var translate_reasoning_7 = "جارٍ إيجاد أفضل طريقة...";
|
|
1503
1816
|
var translate_reasoning_8 = "جارٍ تنظيم أفكاري...";
|
|
1504
1817
|
var translate_reasoning_9 = "أوشك على الانتهاء...";
|
|
1818
|
+
var translate_running = "قيد التنفيذ";
|
|
1819
|
+
var translate_aborted = "تم الإلغاء";
|
|
1505
1820
|
var ar = {
|
|
1506
1821
|
translate_new: translate_new,
|
|
1507
1822
|
translate_threads: translate_threads,
|
|
@@ -1588,7 +1903,9 @@ var ar = {
|
|
|
1588
1903
|
translate_reasoning_6: translate_reasoning_6,
|
|
1589
1904
|
translate_reasoning_7: translate_reasoning_7,
|
|
1590
1905
|
translate_reasoning_8: translate_reasoning_8,
|
|
1591
|
-
translate_reasoning_9: translate_reasoning_9
|
|
1906
|
+
translate_reasoning_9: translate_reasoning_9,
|
|
1907
|
+
translate_running: translate_running,
|
|
1908
|
+
translate_aborted: translate_aborted
|
|
1592
1909
|
};
|
|
1593
1910
|
|
|
1594
1911
|
const translations = { en, ar };
|
|
@@ -1600,10 +1917,10 @@ class CortexClientTranslateLoader {
|
|
|
1600
1917
|
|
|
1601
1918
|
class CortexClientConfigRef {
|
|
1602
1919
|
config;
|
|
1603
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1604
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1920
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexClientConfigRef, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1921
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexClientConfigRef });
|
|
1605
1922
|
}
|
|
1606
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1923
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexClientConfigRef, decorators: [{
|
|
1607
1924
|
type: Injectable
|
|
1608
1925
|
}] });
|
|
1609
1926
|
class CortexChatWidgetComponent {
|
|
@@ -1650,8 +1967,8 @@ class CortexChatWidgetComponent {
|
|
|
1650
1967
|
this.chatService.deselectThread();
|
|
1651
1968
|
this.screen.set('chat');
|
|
1652
1969
|
}
|
|
1653
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1654
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1970
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexChatWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1971
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CortexChatWidgetComponent, isStandalone: true, selector: "cortex-chat-widget", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { text: "textChange" }, host: { classAttribute: "cortex-widget" }, providers: [
|
|
1655
1972
|
CortexClientConfigRef,
|
|
1656
1973
|
{
|
|
1657
1974
|
provide: CORTEX_CLIENT_CONFIG,
|
|
@@ -1663,9 +1980,9 @@ class CortexChatWidgetComponent {
|
|
|
1663
1980
|
fallbackLang: 'en',
|
|
1664
1981
|
loader: provideTranslateLoader(CortexClientTranslateLoader),
|
|
1665
1982
|
}),
|
|
1666
|
-
], ngImport: i0, template: "<div class=\"cortex-widget__container\">\n <!-- SCREEN 1: THREADS -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'threads'\"\n [class.cortex-widget__screen--left]=\"screen() !== 'threads'\"\n >\n <!-- Threads header -->\n <div class=\"cortex-widget__threads-header\">\n <div>\n <h2 class=\"cortex-widget__threads-title\">\n {{ 'translate_threads' | translate }}\n </h2>\n <p class=\"cortex-widget__threads-count\">\n {{\n 'translate_n_conversations' | translate: { count: chatService.threads()?.length ?? 0 }\n }}\n </p>\n </div>\n <button (click)=\"newChat()\" class=\"cortex-widget__new-chat-btn\">\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=\"cortex-widget__threads-list\">\n <!-- Threads loading skeleton -->\n @if (chatService.threads() === undefined) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"cortex-widget__thread-skeleton\">\n <div class=\"cortex-skeleton cortex-widget__thread-skeleton-icon\"></div>\n <div class=\"cortex-widget__thread-skeleton-lines\">\n <div\n class=\"cortex-skeleton cortex-widget__thread-skeleton-line\"\n [style.width]=\"40 + i * 12 + '%'\"\n ></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=\"cortex-widget__thread-item\"\n [class.cortex-widget__thread-item--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n <!-- Thread icon -->\n <div\n class=\"cortex-widget__thread-icon\"\n [class.cortex-widget__thread-icon--active]=\"\n 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=\"cortex-widget__thread-info\">\n <p\n class=\"cortex-widget__thread-title\"\n [class.cortex-widget__thread-title--active]=\"\n 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=\"cortex-widget__thread-delete\"\n [class.cortex-widget__thread-delete--active]=\"\n 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=\"cortex-widget__thread-arrow\"\n [class.cortex-widget__thread-arrow--active]=\"\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=\"cortex-widget__threads-empty\">\n <div class=\"cortex-widget__threads-empty-icon\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__threads-empty-svg\"\n >\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=\"cortex-widget__threads-empty-title\">No threads yet</p>\n <p class=\"cortex-widget__threads-empty-subtitle\">Start a new conversation</p>\n </div>\n }\n }\n </div>\n </div>\n\n <!-- SCREEN 2: CHAT -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'chat'\"\n [class.cortex-widget__screen--right]=\"screen() !== 'chat'\"\n >\n <!-- Chat header -->\n <div class=\"cortex-widget__chat-header\">\n <!-- Back button -->\n <button (click)=\"goBack()\" class=\"cortex-widget__back-btn\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__back-icon\"\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=\"cortex-widget__chat-title-wrap\">\n <p class=\"cortex-widget__chat-title\">\n {{ chatService.selectedThread()?.title ?? ('translate_new_chat' | translate) }}\n </p>\n </div>\n\n <!-- Debug toggle -->\n <button\n (click)=\"toggleDebugMode()\"\n class=\"cortex-widget__debug-btn\"\n [class.cortex-widget__debug-btn--on]=\"debugMode()\"\n [class.cortex-widget__debug-btn--off]=\"!debugMode()\"\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=\"cortex-widget__messages-skeleton\">\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 13rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 9rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 16rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 18rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 12rem\"></div>\n </div>\n </div>\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 11rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 14rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 15rem\"></div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Messages area -->\n <cortex-message-list class=\"cortex-widget__messages\" [debugMode]=\"debugMode()\" />\n }\n\n <!-- Agent working indicator -->\n @if (chatService.isAgentWorking() && !chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__working\">\n <div class=\"cortex-widget__working-dots\">\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n </div>\n <span class=\"cortex-widget__working-text\">{{ 'translate_thinking' | translate }}</span>\n </div>\n }\n\n <!-- Chat input (hidden during pending tool calls) -->\n @if (!chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__input-area\">\n <div\n class=\"cortex-widget__input-box\"\n [class.cortex-widget__input-box--disabled]=\"chatService.isAgentWorking()\"\n [class.cortex-widget__input-box--enabled]=\"!chatService.isAgentWorking()\"\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=\"cortex-widget__textarea\"\n [class.cortex-widget__textarea--disabled]=\"chatService.isAgentWorking()\"\n ></textarea>\n @if (chatService.isAgentWorking()) {\n <!-- Stop button -->\n <button (click)=\"chatService.abort()\" class=\"cortex-stop-btn\">\n <!-- Pulsing ring -->\n <span class=\"cortex-stop-btn__ring\"></span>\n <!-- Stop icon (rounded square) -->\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n class=\"cortex-stop-btn__icon\"\n >\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=\"cortex-widget__send-btn\"\n [class.cortex-widget__send-btn--empty]=\"!text().trim()\"\n [class.cortex-widget__send-btn--ready]=\"!!text().trim()\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__send-icon\"\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", styles: [".cortex-widget{display:block}.cortex-widget__container{width:100%;height:100%;position:relative;overflow:hidden}.cortex-widget__screen{position:absolute;inset:0;display:flex;flex-direction:column;transition:transform .3s ease-out}.cortex-widget__screen--active{transform:translate(0)}.cortex-widget__screen--left{transform:translate(-100%)}[dir=rtl] .cortex-widget__screen--left,.cortex-widget__screen--right{transform:translate(100%)}[dir=rtl] .cortex-widget__screen--right{transform:translate(-100%)}.cortex-widget__threads-header{flex-shrink:0;padding:1.25rem 1.25rem 1rem;display:flex;align-items:center;justify-content:space-between}.cortex-widget__threads-title{font-size:.9375rem;font-weight:600;color:#1e293b;letter-spacing:-.01em;margin:0}.cortex-widget__threads-count{font-size:.6875rem;color:#94a3b8;margin-top:.125rem;margin-bottom:0}.cortex-widget__new-chat-btn{display:inline-flex;align-items:center;gap:.375rem;font-size:.75rem;font-weight:500;color:#f1f5f9;background:#1e293b;padding:.375rem .75rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__new-chat-btn:hover{background:#334155}.cortex-widget__new-chat-btn:active{background:#0f172a}.cortex-widget__threads-list{flex:1;overflow-y:auto;padding:0 .75rem .75rem}.cortex-widget__thread-skeleton{display:flex;align-items:center;gap:.75rem;padding:.75rem;margin-bottom:.125rem}.cortex-widget__thread-skeleton-icon{flex-shrink:0;width:2rem;height:2rem}.cortex-widget__thread-skeleton-lines{flex:1;display:flex;flex-direction:column;gap:.375rem}.cortex-widget__thread-skeleton-line{height:.875rem}@keyframes cortex-skeleton-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.cortex-skeleton{background:linear-gradient(90deg,#e2e8f0,#f1f5f9,#e2e8f0 80%);background-size:200% 100%;animation:cortex-skeleton-shimmer 1.8s ease-in-out infinite;border-radius:6px}.cortex-widget__thread-item{width:100%;text-align:start;padding:.75rem;border-radius:.5rem;display:flex;align-items:center;gap:.75rem;transition:background-color .15s;cursor:pointer;margin-bottom:.125rem;border:0;background:transparent;color:#475569}.cortex-widget__thread-item:hover{background:#f1f5f9}.cortex-widget__thread-item:active{background:#e8ecf1}.cortex-widget__thread-item--active{background:#e2e8f0;color:#f1f5f9}.cortex-widget__thread-icon{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;font-size:.6875rem;font-weight:600;background:#e2e8f0;color:#64748b}[dir=rtl] .cortex-widget__thread-icon{transform:rotate(180deg)}.cortex-widget__thread-icon--active{background:#334155;color:#cbd5e1}.cortex-widget__thread-info{min-width:0;flex:1}.cortex-widget__thread-title{font-size:.8125rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.25;margin:0;color:#334155}.cortex-widget__thread-title--active{color:#f1f5f9}.cortex-widget__thread-delete{flex-shrink:0;opacity:0;width:1.75rem;height:1.75rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s;background:transparent;border:0;color:#94a3b8}.cortex-widget__thread-item:hover>.cortex-widget__thread-delete{opacity:1}.cortex-widget__thread-delete:hover{background:#e2e8f0}.cortex-widget__thread-delete--active:hover{background:#475569}.cortex-widget__thread-arrow{flex-shrink:0;transition:color .15s;color:#cbd5e1}[dir=rtl] .cortex-widget__thread-arrow{transform:rotate(180deg)}.cortex-widget__thread-item:hover>.cortex-widget__thread-arrow{color:#94a3b8}.cortex-widget__thread-arrow--active{color:#64748b}.cortex-widget__threads-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:4rem 0;text-align:center}.cortex-widget__threads-empty-icon{width:2.5rem;height:2.5rem;border-radius:.5rem;background:#e2e8f0;display:flex;align-items:center;justify-content:center;margin-bottom:.75rem}.cortex-widget__threads-empty-svg{color:#94a3b8}.cortex-widget__threads-empty-title{font-size:.8125rem;color:#94a3b8;font-weight:500;margin:0}.cortex-widget__threads-empty-subtitle{font-size:.6875rem;color:#a5afbd;margin-top:.25rem;margin-bottom:0}.cortex-widget__chat-header{flex-shrink:0;height:3rem;padding:0 1rem;display:flex;align-items:center;gap:.75rem;border-bottom:1px solid #e2e8f0;background:#fff}.cortex-widget__back-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;color:#94a3b8;background:transparent;border:0;cursor:pointer;transition:color .15s,background-color .15s}.cortex-widget__back-btn:hover{color:#475569;background:#f1f5f9}[dir=rtl] .cortex-widget__back-icon{transform:rotate(180deg)}.cortex-widget__chat-title-wrap{min-width:0;flex:1}.cortex-widget__chat-title{font-size:.8125rem;font-weight:500;color:#334155;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.cortex-widget__debug-btn{flex-shrink:0;font-size:.6875rem;font-weight:500;padding:.25rem .625rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__debug-btn--on{background:#fef3c7;color:#d97706}.cortex-widget__debug-btn--on:hover{background:#fde68a}.cortex-widget__debug-btn--off{background:#f1f5f9;color:#94a3b8}.cortex-widget__debug-btn--off:hover{background:#e2e8f0}.cortex-widget__messages-skeleton{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel{width:100%;display:flex;flex-direction:column}.cortex-widget__msg-skel--user{align-items:flex-end}.cortex-widget__msg-skel--assistant{align-items:flex-start}.cortex-widget__msg-skel-bubble{max-width:80%;padding:1rem;border-radius:1rem;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel-bubble--user{background:#f8fafc;border-bottom-right-radius:0}.cortex-widget__msg-skel-bubble--assistant{background:#f1f5f9;border-bottom-left-radius:0}.cortex-widget__msg-skel-line{height:.75rem}.cortex-widget__messages{flex:1;overflow:hidden}@keyframes cortex-working-slide-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes cortex-dot-wave{0%,60%,to{transform:translateY(0) scale(1);opacity:.45}30%{transform:translateY(-5px) scale(1.2);opacity:1}}@keyframes cortex-working-shimmer{0%{background-position:-200% center}to{background-position:200% center}}.cortex-widget__working{flex-shrink:0;padding:.5rem 1rem;display:flex;align-items:center;gap:.5rem;animation:cortex-working-slide-in .25s ease-out both}.cortex-widget__working-dots{display:flex;align-items:center;gap:4px}.cortex-working-dot{display:block;width:6px;height:6px;border-radius:9999px;background:#22c55e;animation:cortex-dot-wave 1.4s ease-in-out infinite}.cortex-working-dot:nth-child(2){animation-delay:.15s}.cortex-working-dot:nth-child(3){animation-delay:.3s}.cortex-widget__working-text{font-size:.75rem;font-weight:500;letter-spacing:.01em;color:#16a34a}.cortex-widget__input-area{flex-shrink:0;padding:.75rem;background:#fff;border-top:1px solid #e2e8f0}.cortex-widget__input-box{display:flex;align-items:flex-end;gap:.5rem;border-radius:.75rem;border:1px solid #e2e8f0;padding:.375rem;transition:border-color .15s,background-color .15s}.cortex-widget__input-box--disabled{background:#f1f5f9}.cortex-widget__input-box--enabled{background:#f8fafc}.cortex-widget__input-box--enabled:focus-within{border-color:#cbd5e1;background:#fff}.cortex-widget__textarea{flex:1;background:transparent;resize:none;border:0;outline:none;font-size:.8125rem;padding:.375rem .5rem;min-height:28px;max-height:120px;line-height:1.375;color:#334155}.cortex-widget__textarea::placeholder{color:#a5afbd}.cortex-widget__textarea--disabled{color:#94a3b8;cursor:not-allowed}.cortex-widget__textarea:disabled{cursor:not-allowed;border:0}@keyframes cortex-stop-pulse-ring{0%{opacity:.45;transform:scale(1)}50%{opacity:.15;transform:scale(1.12)}to{opacity:.45;transform:scale(1)}}@keyframes cortex-stop-fade-in{0%{opacity:0;transform:scale(.7)}to{opacity:1;transform:scale(1)}}.cortex-stop-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;background:#e11d48;color:#fff;border:0;animation:cortex-stop-fade-in .2s ease-out both;transition:background .15s ease}.cortex-stop-btn:hover{background:#be123c}.cortex-stop-btn:active{transform:scale(.92)}.cortex-stop-btn__ring{position:absolute;inset:0;border-radius:.5rem;background:#e11d48;animation:cortex-stop-pulse-ring 2s ease-in-out infinite;pointer-events:none}.cortex-stop-btn__icon{position:relative;z-index:1}.cortex-widget__send-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;border:0;transition:background-color .15s}.cortex-widget__send-btn--empty{background:#e2e8f0;color:#94a3b8}.cortex-widget__send-btn--ready{background:#1e293b;color:#fff;cursor:pointer}.cortex-widget__send-btn--ready:hover{background:#334155}[dir=rtl] .cortex-widget__send-icon{transform:rotate(180deg)}\n"], dependencies: [{ kind: "component", type: MessageListComponent, selector: "cortex-message-list", inputs: ["debugMode"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1983
|
+
], ngImport: i0, template: "<div class=\"cortex-widget__container\">\n <!-- SCREEN 1: THREADS -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'threads'\"\n [class.cortex-widget__screen--left]=\"screen() !== 'threads'\"\n >\n <!-- Threads header -->\n <div class=\"cortex-widget__threads-header\">\n <div>\n <h2 class=\"cortex-widget__threads-title\">\n {{ 'translate_threads' | translate }}\n </h2>\n <p class=\"cortex-widget__threads-count\">\n {{\n 'translate_n_conversations' | translate: { count: chatService.threads()?.length ?? 0 }\n }}\n </p>\n </div>\n <button (click)=\"newChat()\" class=\"cortex-widget__new-chat-btn\">\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=\"cortex-widget__threads-list\">\n <!-- Threads loading skeleton -->\n @if (chatService.threads() === undefined) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"cortex-widget__thread-skeleton\">\n <div class=\"cortex-skeleton cortex-widget__thread-skeleton-icon\"></div>\n <div class=\"cortex-widget__thread-skeleton-lines\">\n <div\n class=\"cortex-skeleton cortex-widget__thread-skeleton-line\"\n [style.width]=\"40 + i * 12 + '%'\"\n ></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=\"cortex-widget__thread-item\"\n [class.cortex-widget__thread-item--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n <!-- Thread icon -->\n <div\n class=\"cortex-widget__thread-icon\"\n [class.cortex-widget__thread-icon--active]=\"\n 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=\"cortex-widget__thread-info\">\n <div class=\"cortex-widget__thread-title-row\">\n <p\n class=\"cortex-widget__thread-title\"\n [class.cortex-widget__thread-title--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n {{ thread.title ?? ('translate_untitled' | translate) }}\n </p>\n\n @if (thread.isRunning) {\n <span\n class=\"cortex-widget__thread-running\"\n [class.cortex-widget__thread-running--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n <span class=\"cortex-widget__thread-running-dot\"></span>\n {{ 'translate_running' | translate }}\n </span>\n }\n </div>\n </div>\n\n <!-- Delete button -->\n <button\n (click)=\"$event.stopPropagation(); chatService.deleteThread(thread.id).subscribe()\"\n class=\"cortex-widget__thread-delete\"\n [class.cortex-widget__thread-delete--active]=\"\n 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=\"cortex-widget__thread-arrow\"\n [class.cortex-widget__thread-arrow--active]=\"\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=\"cortex-widget__threads-empty\">\n <div class=\"cortex-widget__threads-empty-icon\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__threads-empty-svg\"\n >\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=\"cortex-widget__threads-empty-title\">No threads yet</p>\n <p class=\"cortex-widget__threads-empty-subtitle\">Start a new conversation</p>\n </div>\n }\n }\n </div>\n </div>\n\n <!-- SCREEN 2: CHAT -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'chat'\"\n [class.cortex-widget__screen--right]=\"screen() !== 'chat'\"\n >\n <!-- Chat header -->\n <div class=\"cortex-widget__chat-header\">\n <!-- Back button -->\n <button (click)=\"goBack()\" class=\"cortex-widget__back-btn\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__back-icon\"\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=\"cortex-widget__chat-title-wrap\">\n <p class=\"cortex-widget__chat-title\">\n {{ chatService.selectedThread()?.title ?? ('translate_new_chat' | translate) }}\n </p>\n </div>\n\n <!-- Debug toggle -->\n @if (config().showDebugButton) {\n <button\n (click)=\"toggleDebugMode()\"\n class=\"cortex-widget__debug-btn\"\n [class.cortex-widget__debug-btn--on]=\"debugMode()\"\n [class.cortex-widget__debug-btn--off]=\"!debugMode()\"\n >\n {{ debugMode() ? ('translate_debug' | translate) : ('translate_normal' | translate) }}\n </button>\n }\n </div>\n\n <!-- Messages loading skeleton -->\n @if (chatService.isLoadingMessages() && !chatService.isAgentWorking()) {\n <div class=\"cortex-widget__messages-skeleton\">\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 13rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 9rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 16rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 18rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 12rem\"></div>\n </div>\n </div>\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 11rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 14rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 15rem\"></div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Messages area -->\n <cortex-message-list class=\"cortex-widget__messages\" [debugMode]=\"debugMode()\" />\n }\n\n <!-- Agent working indicator -->\n @if (chatService.isAgentWorking() && !chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__working\">\n <div class=\"cortex-widget__working-dots\">\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n </div>\n <span class=\"cortex-widget__working-text\">{{ 'translate_thinking' | translate }}</span>\n </div>\n }\n\n <!-- Chat input (hidden during pending tool calls) -->\n @if (!chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__input-area\">\n <div\n class=\"cortex-widget__input-box\"\n [class.cortex-widget__input-box--disabled]=\"chatService.isAgentWorking()\"\n [class.cortex-widget__input-box--enabled]=\"!chatService.isAgentWorking()\"\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=\"cortex-widget__textarea\"\n [class.cortex-widget__textarea--disabled]=\"chatService.isAgentWorking()\"\n ></textarea>\n @if (chatService.isAgentWorking()) {\n <!-- Stop button -->\n <button (click)=\"chatService.abort()\" class=\"cortex-stop-btn\">\n <!-- Pulsing ring -->\n <span class=\"cortex-stop-btn__ring\"></span>\n <!-- Stop icon (rounded square) -->\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n class=\"cortex-stop-btn__icon\"\n >\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=\"cortex-widget__send-btn\"\n [class.cortex-widget__send-btn--empty]=\"!text().trim()\"\n [class.cortex-widget__send-btn--ready]=\"!!text().trim()\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__send-icon\"\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", styles: [".cortex-widget{display:block}.cortex-widget__container{width:100%;height:100%;position:relative;overflow:hidden}.cortex-widget__screen{position:absolute;inset:0;display:flex;flex-direction:column;transition:transform .3s ease-out}.cortex-widget__screen--active{transform:translate(0)}.cortex-widget__screen--left{transform:translate(-100%)}[dir=rtl] .cortex-widget__screen--left,.cortex-widget__screen--right{transform:translate(100%)}[dir=rtl] .cortex-widget__screen--right{transform:translate(-100%)}.cortex-widget__threads-header{flex-shrink:0;padding:1.25rem 1.25rem 1rem;display:flex;align-items:center;justify-content:space-between}.cortex-widget__threads-title{font-size:.9375rem;font-weight:600;color:#1e293b;letter-spacing:-.01em;margin:0}.cortex-widget__threads-count{font-size:.6875rem;color:#94a3b8;margin-top:.125rem;margin-bottom:0}.cortex-widget__new-chat-btn{display:inline-flex;align-items:center;gap:.375rem;font-size:.75rem;font-weight:500;color:#f1f5f9;background:#1e293b;padding:.375rem .75rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__new-chat-btn:hover{background:#334155}.cortex-widget__new-chat-btn:active{background:#0f172a}.cortex-widget__threads-list{flex:1;overflow-y:auto;padding:0 .75rem .75rem}.cortex-widget__thread-skeleton{display:flex;align-items:center;gap:.75rem;padding:.75rem;margin-bottom:.125rem}.cortex-widget__thread-skeleton-icon{flex-shrink:0;width:2rem;height:2rem}.cortex-widget__thread-skeleton-lines{flex:1;display:flex;flex-direction:column;gap:.375rem}.cortex-widget__thread-skeleton-line{height:.875rem}@keyframes cortex-skeleton-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.cortex-skeleton{background:linear-gradient(90deg,#e2e8f0,#f1f5f9,#e2e8f0 80%);background-size:200% 100%;animation:cortex-skeleton-shimmer 1.8s ease-in-out infinite;border-radius:6px}.cortex-widget__thread-item{width:100%;text-align:start;padding:.75rem;border-radius:.5rem;display:flex;align-items:center;gap:.75rem;transition:background-color .15s;cursor:pointer;margin-bottom:.125rem;border:0;background:transparent;color:#475569}.cortex-widget__thread-item:hover{background:#f1f5f9}.cortex-widget__thread-item:active{background:#e8ecf1}.cortex-widget__thread-item--active{background:#e2e8f0;color:#f1f5f9}.cortex-widget__thread-icon{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;font-size:.6875rem;font-weight:600;background:#e2e8f0;color:#64748b}[dir=rtl] .cortex-widget__thread-icon{transform:rotate(180deg)}.cortex-widget__thread-icon--active{background:#334155;color:#cbd5e1}.cortex-widget__thread-info{min-width:0;flex:1}.cortex-widget__thread-title-row{display:flex;align-items:center;gap:.5rem;min-width:0}.cortex-widget__thread-title{font-size:.8125rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.25;margin:0;color:#334155}.cortex-widget__thread-title--active{color:#f1f5f9}.cortex-widget__thread-running{flex-shrink:0;display:inline-flex;align-items:center;gap:.3125rem;padding:.2rem .45rem;border-radius:999px;background:#0e74901a;color:#0f766e;font-size:.625rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase}.cortex-widget__thread-running--active{background:#f1f5f929;color:#e2e8f0}.cortex-widget__thread-running-dot{width:.375rem;height:.375rem;border-radius:999px;background:currentColor;box-shadow:0 0 .45rem currentColor;animation:cortex-thread-running-pulse 1.4s ease-in-out infinite}@keyframes cortex-thread-running-pulse{0%,to{opacity:.45;transform:scale(.9)}50%{opacity:1;transform:scale(1)}}.cortex-widget__thread-delete{flex-shrink:0;opacity:0;width:1.75rem;height:1.75rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s;background:transparent;border:0;color:#94a3b8}.cortex-widget__thread-item:hover>.cortex-widget__thread-delete{opacity:1}.cortex-widget__thread-delete:hover{background:#e2e8f0}.cortex-widget__thread-delete--active:hover{background:#475569}.cortex-widget__thread-arrow{flex-shrink:0;transition:color .15s;color:#cbd5e1}[dir=rtl] .cortex-widget__thread-arrow{transform:rotate(180deg)}.cortex-widget__thread-item:hover>.cortex-widget__thread-arrow{color:#94a3b8}.cortex-widget__thread-arrow--active{color:#64748b}.cortex-widget__threads-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:4rem 0;text-align:center}.cortex-widget__threads-empty-icon{width:2.5rem;height:2.5rem;border-radius:.5rem;background:#e2e8f0;display:flex;align-items:center;justify-content:center;margin-bottom:.75rem}.cortex-widget__threads-empty-svg{color:#94a3b8}.cortex-widget__threads-empty-title{font-size:.8125rem;color:#94a3b8;font-weight:500;margin:0}.cortex-widget__threads-empty-subtitle{font-size:.6875rem;color:#a5afbd;margin-top:.25rem;margin-bottom:0}.cortex-widget__chat-header{flex-shrink:0;height:3rem;padding:0 1rem;display:flex;align-items:center;gap:.75rem;border-bottom:1px solid #e2e8f0;background:#fff}.cortex-widget__back-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;color:#94a3b8;background:transparent;border:0;cursor:pointer;transition:color .15s,background-color .15s}.cortex-widget__back-btn:hover{color:#475569;background:#f1f5f9}[dir=rtl] .cortex-widget__back-icon{transform:rotate(180deg)}.cortex-widget__chat-title-wrap{min-width:0;flex:1}.cortex-widget__chat-title{font-size:.8125rem;font-weight:500;color:#334155;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.cortex-widget__debug-btn{flex-shrink:0;font-size:.6875rem;font-weight:500;padding:.25rem .625rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__debug-btn--on{background:#fef3c7;color:#d97706}.cortex-widget__debug-btn--on:hover{background:#fde68a}.cortex-widget__debug-btn--off{background:#f1f5f9;color:#94a3b8}.cortex-widget__debug-btn--off:hover{background:#e2e8f0}.cortex-widget__messages-skeleton{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel{width:100%;display:flex;flex-direction:column}.cortex-widget__msg-skel--user{align-items:flex-end}.cortex-widget__msg-skel--assistant{align-items:flex-start}.cortex-widget__msg-skel-bubble{max-width:80%;padding:1rem;border-radius:1rem;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel-bubble--user{background:#f8fafc;border-bottom-right-radius:0}.cortex-widget__msg-skel-bubble--assistant{background:#f1f5f9;border-bottom-left-radius:0}.cortex-widget__msg-skel-line{height:.75rem}.cortex-widget__messages{flex:1;overflow:hidden}@keyframes cortex-working-slide-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes cortex-dot-wave{0%,60%,to{transform:translateY(0) scale(1);opacity:.45}30%{transform:translateY(-5px) scale(1.2);opacity:1}}@keyframes cortex-working-shimmer{0%{background-position:-200% center}to{background-position:200% center}}.cortex-widget__working{flex-shrink:0;padding:.5rem 1rem;display:flex;align-items:center;gap:.5rem;animation:cortex-working-slide-in .25s ease-out both}.cortex-widget__working-dots{display:flex;align-items:center;gap:4px}.cortex-working-dot{display:block;width:6px;height:6px;border-radius:9999px;background:#22c55e;animation:cortex-dot-wave 1.4s ease-in-out infinite}.cortex-working-dot:nth-child(2){animation-delay:.15s}.cortex-working-dot:nth-child(3){animation-delay:.3s}.cortex-widget__working-text{font-size:.75rem;font-weight:500;letter-spacing:.01em;color:#16a34a}.cortex-widget__input-area{flex-shrink:0;padding:.75rem;background:#fff;border-top:1px solid #e2e8f0}.cortex-widget__input-box{display:flex;align-items:flex-end;gap:.5rem;border-radius:.75rem;border:1px solid #e2e8f0;padding:.375rem;transition:border-color .15s,background-color .15s}.cortex-widget__input-box--disabled{background:#f1f5f9}.cortex-widget__input-box--enabled{background:#f8fafc}.cortex-widget__input-box--enabled:focus-within{border-color:#cbd5e1;background:#fff}.cortex-widget__textarea{flex:1;background:transparent;resize:none;border:0;outline:none;font-size:.8125rem;padding:.375rem .5rem;min-height:28px;max-height:120px;line-height:1.375;color:#334155}.cortex-widget__textarea::placeholder{color:#a5afbd}.cortex-widget__textarea--disabled{color:#94a3b8;cursor:not-allowed}.cortex-widget__textarea:disabled{cursor:not-allowed;border:0}@keyframes cortex-stop-pulse-ring{0%{opacity:.45;transform:scale(1)}50%{opacity:.15;transform:scale(1.12)}to{opacity:.45;transform:scale(1)}}@keyframes cortex-stop-fade-in{0%{opacity:0;transform:scale(.7)}to{opacity:1;transform:scale(1)}}.cortex-stop-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;background:#e11d48;color:#fff;border:0;animation:cortex-stop-fade-in .2s ease-out both;transition:background .15s ease}.cortex-stop-btn:hover{background:#be123c}.cortex-stop-btn:active{transform:scale(.92)}.cortex-stop-btn__ring{position:absolute;inset:0;border-radius:.5rem;background:#e11d48;animation:cortex-stop-pulse-ring 2s ease-in-out infinite;pointer-events:none}.cortex-stop-btn__icon{position:relative;z-index:1}.cortex-widget__send-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;border:0;transition:background-color .15s}.cortex-widget__send-btn--empty{background:#e2e8f0;color:#94a3b8}.cortex-widget__send-btn--ready{background:#1e293b;color:#fff;cursor:pointer}.cortex-widget__send-btn--ready:hover{background:#334155}[dir=rtl] .cortex-widget__send-icon{transform:rotate(180deg)}\n"], dependencies: [{ kind: "component", type: MessageListComponent, selector: "cortex-message-list", inputs: ["debugMode"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1667
1984
|
}
|
|
1668
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1985
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CortexChatWidgetComponent, decorators: [{
|
|
1669
1986
|
type: Component,
|
|
1670
1987
|
args: [{ selector: 'cortex-chat-widget', imports: [MessageListComponent, FormsModule, TranslatePipe], providers: [
|
|
1671
1988
|
CortexClientConfigRef,
|
|
@@ -1679,7 +1996,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImpor
|
|
|
1679
1996
|
fallbackLang: 'en',
|
|
1680
1997
|
loader: provideTranslateLoader(CortexClientTranslateLoader),
|
|
1681
1998
|
}),
|
|
1682
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'cortex-widget' }, template: "<div class=\"cortex-widget__container\">\n <!-- SCREEN 1: THREADS -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'threads'\"\n [class.cortex-widget__screen--left]=\"screen() !== 'threads'\"\n >\n <!-- Threads header -->\n <div class=\"cortex-widget__threads-header\">\n <div>\n <h2 class=\"cortex-widget__threads-title\">\n {{ 'translate_threads' | translate }}\n </h2>\n <p class=\"cortex-widget__threads-count\">\n {{\n 'translate_n_conversations' | translate: { count: chatService.threads()?.length ?? 0 }\n }}\n </p>\n </div>\n <button (click)=\"newChat()\" class=\"cortex-widget__new-chat-btn\">\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=\"cortex-widget__threads-list\">\n <!-- Threads loading skeleton -->\n @if (chatService.threads() === undefined) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"cortex-widget__thread-skeleton\">\n <div class=\"cortex-skeleton cortex-widget__thread-skeleton-icon\"></div>\n <div class=\"cortex-widget__thread-skeleton-lines\">\n <div\n class=\"cortex-skeleton cortex-widget__thread-skeleton-line\"\n [style.width]=\"40 + i * 12 + '%'\"\n ></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=\"cortex-widget__thread-item\"\n [class.cortex-widget__thread-item--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n <!-- Thread icon -->\n <div\n class=\"cortex-widget__thread-icon\"\n [class.cortex-widget__thread-icon--active]=\"\n 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=\"cortex-widget__thread-info\">\n <p\n class=\"cortex-widget__thread-title\"\n [class.cortex-widget__thread-title--active]=\"\n 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=\"cortex-widget__thread-delete\"\n [class.cortex-widget__thread-delete--active]=\"\n 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=\"cortex-widget__thread-arrow\"\n [class.cortex-widget__thread-arrow--active]=\"\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=\"cortex-widget__threads-empty\">\n <div class=\"cortex-widget__threads-empty-icon\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__threads-empty-svg\"\n >\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=\"cortex-widget__threads-empty-title\">No threads yet</p>\n <p class=\"cortex-widget__threads-empty-subtitle\">Start a new conversation</p>\n </div>\n }\n }\n </div>\n </div>\n\n <!-- SCREEN 2: CHAT -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'chat'\"\n [class.cortex-widget__screen--right]=\"screen() !== 'chat'\"\n >\n <!-- Chat header -->\n <div class=\"cortex-widget__chat-header\">\n <!-- Back button -->\n <button (click)=\"goBack()\" class=\"cortex-widget__back-btn\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__back-icon\"\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=\"cortex-widget__chat-title-wrap\">\n <p class=\"cortex-widget__chat-title\">\n {{ chatService.selectedThread()?.title ?? ('translate_new_chat' | translate) }}\n </p>\n </div>\n\n <!-- Debug toggle -->\n <button\n (click)=\"toggleDebugMode()\"\n class=\"cortex-widget__debug-btn\"\n [class.cortex-widget__debug-btn--on]=\"debugMode()\"\n [class.cortex-widget__debug-btn--off]=\"!debugMode()\"\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=\"cortex-widget__messages-skeleton\">\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 13rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 9rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 16rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 18rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 12rem\"></div>\n </div>\n </div>\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 11rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 14rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 15rem\"></div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Messages area -->\n <cortex-message-list class=\"cortex-widget__messages\" [debugMode]=\"debugMode()\" />\n }\n\n <!-- Agent working indicator -->\n @if (chatService.isAgentWorking() && !chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__working\">\n <div class=\"cortex-widget__working-dots\">\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n </div>\n <span class=\"cortex-widget__working-text\">{{ 'translate_thinking' | translate }}</span>\n </div>\n }\n\n <!-- Chat input (hidden during pending tool calls) -->\n @if (!chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__input-area\">\n <div\n class=\"cortex-widget__input-box\"\n [class.cortex-widget__input-box--disabled]=\"chatService.isAgentWorking()\"\n [class.cortex-widget__input-box--enabled]=\"!chatService.isAgentWorking()\"\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=\"cortex-widget__textarea\"\n [class.cortex-widget__textarea--disabled]=\"chatService.isAgentWorking()\"\n ></textarea>\n @if (chatService.isAgentWorking()) {\n <!-- Stop button -->\n <button (click)=\"chatService.abort()\" class=\"cortex-stop-btn\">\n <!-- Pulsing ring -->\n <span class=\"cortex-stop-btn__ring\"></span>\n <!-- Stop icon (rounded square) -->\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n class=\"cortex-stop-btn__icon\"\n >\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=\"cortex-widget__send-btn\"\n [class.cortex-widget__send-btn--empty]=\"!text().trim()\"\n [class.cortex-widget__send-btn--ready]=\"!!text().trim()\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__send-icon\"\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", styles: [".cortex-widget{display:block}.cortex-widget__container{width:100%;height:100%;position:relative;overflow:hidden}.cortex-widget__screen{position:absolute;inset:0;display:flex;flex-direction:column;transition:transform .3s ease-out}.cortex-widget__screen--active{transform:translate(0)}.cortex-widget__screen--left{transform:translate(-100%)}[dir=rtl] .cortex-widget__screen--left,.cortex-widget__screen--right{transform:translate(100%)}[dir=rtl] .cortex-widget__screen--right{transform:translate(-100%)}.cortex-widget__threads-header{flex-shrink:0;padding:1.25rem 1.25rem 1rem;display:flex;align-items:center;justify-content:space-between}.cortex-widget__threads-title{font-size:.9375rem;font-weight:600;color:#1e293b;letter-spacing:-.01em;margin:0}.cortex-widget__threads-count{font-size:.6875rem;color:#94a3b8;margin-top:.125rem;margin-bottom:0}.cortex-widget__new-chat-btn{display:inline-flex;align-items:center;gap:.375rem;font-size:.75rem;font-weight:500;color:#f1f5f9;background:#1e293b;padding:.375rem .75rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__new-chat-btn:hover{background:#334155}.cortex-widget__new-chat-btn:active{background:#0f172a}.cortex-widget__threads-list{flex:1;overflow-y:auto;padding:0 .75rem .75rem}.cortex-widget__thread-skeleton{display:flex;align-items:center;gap:.75rem;padding:.75rem;margin-bottom:.125rem}.cortex-widget__thread-skeleton-icon{flex-shrink:0;width:2rem;height:2rem}.cortex-widget__thread-skeleton-lines{flex:1;display:flex;flex-direction:column;gap:.375rem}.cortex-widget__thread-skeleton-line{height:.875rem}@keyframes cortex-skeleton-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.cortex-skeleton{background:linear-gradient(90deg,#e2e8f0,#f1f5f9,#e2e8f0 80%);background-size:200% 100%;animation:cortex-skeleton-shimmer 1.8s ease-in-out infinite;border-radius:6px}.cortex-widget__thread-item{width:100%;text-align:start;padding:.75rem;border-radius:.5rem;display:flex;align-items:center;gap:.75rem;transition:background-color .15s;cursor:pointer;margin-bottom:.125rem;border:0;background:transparent;color:#475569}.cortex-widget__thread-item:hover{background:#f1f5f9}.cortex-widget__thread-item:active{background:#e8ecf1}.cortex-widget__thread-item--active{background:#e2e8f0;color:#f1f5f9}.cortex-widget__thread-icon{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;font-size:.6875rem;font-weight:600;background:#e2e8f0;color:#64748b}[dir=rtl] .cortex-widget__thread-icon{transform:rotate(180deg)}.cortex-widget__thread-icon--active{background:#334155;color:#cbd5e1}.cortex-widget__thread-info{min-width:0;flex:1}.cortex-widget__thread-title{font-size:.8125rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.25;margin:0;color:#334155}.cortex-widget__thread-title--active{color:#f1f5f9}.cortex-widget__thread-delete{flex-shrink:0;opacity:0;width:1.75rem;height:1.75rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s;background:transparent;border:0;color:#94a3b8}.cortex-widget__thread-item:hover>.cortex-widget__thread-delete{opacity:1}.cortex-widget__thread-delete:hover{background:#e2e8f0}.cortex-widget__thread-delete--active:hover{background:#475569}.cortex-widget__thread-arrow{flex-shrink:0;transition:color .15s;color:#cbd5e1}[dir=rtl] .cortex-widget__thread-arrow{transform:rotate(180deg)}.cortex-widget__thread-item:hover>.cortex-widget__thread-arrow{color:#94a3b8}.cortex-widget__thread-arrow--active{color:#64748b}.cortex-widget__threads-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:4rem 0;text-align:center}.cortex-widget__threads-empty-icon{width:2.5rem;height:2.5rem;border-radius:.5rem;background:#e2e8f0;display:flex;align-items:center;justify-content:center;margin-bottom:.75rem}.cortex-widget__threads-empty-svg{color:#94a3b8}.cortex-widget__threads-empty-title{font-size:.8125rem;color:#94a3b8;font-weight:500;margin:0}.cortex-widget__threads-empty-subtitle{font-size:.6875rem;color:#a5afbd;margin-top:.25rem;margin-bottom:0}.cortex-widget__chat-header{flex-shrink:0;height:3rem;padding:0 1rem;display:flex;align-items:center;gap:.75rem;border-bottom:1px solid #e2e8f0;background:#fff}.cortex-widget__back-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;color:#94a3b8;background:transparent;border:0;cursor:pointer;transition:color .15s,background-color .15s}.cortex-widget__back-btn:hover{color:#475569;background:#f1f5f9}[dir=rtl] .cortex-widget__back-icon{transform:rotate(180deg)}.cortex-widget__chat-title-wrap{min-width:0;flex:1}.cortex-widget__chat-title{font-size:.8125rem;font-weight:500;color:#334155;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.cortex-widget__debug-btn{flex-shrink:0;font-size:.6875rem;font-weight:500;padding:.25rem .625rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__debug-btn--on{background:#fef3c7;color:#d97706}.cortex-widget__debug-btn--on:hover{background:#fde68a}.cortex-widget__debug-btn--off{background:#f1f5f9;color:#94a3b8}.cortex-widget__debug-btn--off:hover{background:#e2e8f0}.cortex-widget__messages-skeleton{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel{width:100%;display:flex;flex-direction:column}.cortex-widget__msg-skel--user{align-items:flex-end}.cortex-widget__msg-skel--assistant{align-items:flex-start}.cortex-widget__msg-skel-bubble{max-width:80%;padding:1rem;border-radius:1rem;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel-bubble--user{background:#f8fafc;border-bottom-right-radius:0}.cortex-widget__msg-skel-bubble--assistant{background:#f1f5f9;border-bottom-left-radius:0}.cortex-widget__msg-skel-line{height:.75rem}.cortex-widget__messages{flex:1;overflow:hidden}@keyframes cortex-working-slide-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes cortex-dot-wave{0%,60%,to{transform:translateY(0) scale(1);opacity:.45}30%{transform:translateY(-5px) scale(1.2);opacity:1}}@keyframes cortex-working-shimmer{0%{background-position:-200% center}to{background-position:200% center}}.cortex-widget__working{flex-shrink:0;padding:.5rem 1rem;display:flex;align-items:center;gap:.5rem;animation:cortex-working-slide-in .25s ease-out both}.cortex-widget__working-dots{display:flex;align-items:center;gap:4px}.cortex-working-dot{display:block;width:6px;height:6px;border-radius:9999px;background:#22c55e;animation:cortex-dot-wave 1.4s ease-in-out infinite}.cortex-working-dot:nth-child(2){animation-delay:.15s}.cortex-working-dot:nth-child(3){animation-delay:.3s}.cortex-widget__working-text{font-size:.75rem;font-weight:500;letter-spacing:.01em;color:#16a34a}.cortex-widget__input-area{flex-shrink:0;padding:.75rem;background:#fff;border-top:1px solid #e2e8f0}.cortex-widget__input-box{display:flex;align-items:flex-end;gap:.5rem;border-radius:.75rem;border:1px solid #e2e8f0;padding:.375rem;transition:border-color .15s,background-color .15s}.cortex-widget__input-box--disabled{background:#f1f5f9}.cortex-widget__input-box--enabled{background:#f8fafc}.cortex-widget__input-box--enabled:focus-within{border-color:#cbd5e1;background:#fff}.cortex-widget__textarea{flex:1;background:transparent;resize:none;border:0;outline:none;font-size:.8125rem;padding:.375rem .5rem;min-height:28px;max-height:120px;line-height:1.375;color:#334155}.cortex-widget__textarea::placeholder{color:#a5afbd}.cortex-widget__textarea--disabled{color:#94a3b8;cursor:not-allowed}.cortex-widget__textarea:disabled{cursor:not-allowed;border:0}@keyframes cortex-stop-pulse-ring{0%{opacity:.45;transform:scale(1)}50%{opacity:.15;transform:scale(1.12)}to{opacity:.45;transform:scale(1)}}@keyframes cortex-stop-fade-in{0%{opacity:0;transform:scale(.7)}to{opacity:1;transform:scale(1)}}.cortex-stop-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;background:#e11d48;color:#fff;border:0;animation:cortex-stop-fade-in .2s ease-out both;transition:background .15s ease}.cortex-stop-btn:hover{background:#be123c}.cortex-stop-btn:active{transform:scale(.92)}.cortex-stop-btn__ring{position:absolute;inset:0;border-radius:.5rem;background:#e11d48;animation:cortex-stop-pulse-ring 2s ease-in-out infinite;pointer-events:none}.cortex-stop-btn__icon{position:relative;z-index:1}.cortex-widget__send-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;border:0;transition:background-color .15s}.cortex-widget__send-btn--empty{background:#e2e8f0;color:#94a3b8}.cortex-widget__send-btn--ready{background:#1e293b;color:#fff;cursor:pointer}.cortex-widget__send-btn--ready:hover{background:#334155}[dir=rtl] .cortex-widget__send-icon{transform:rotate(180deg)}\n"] }]
|
|
1999
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'cortex-widget' }, template: "<div class=\"cortex-widget__container\">\n <!-- SCREEN 1: THREADS -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'threads'\"\n [class.cortex-widget__screen--left]=\"screen() !== 'threads'\"\n >\n <!-- Threads header -->\n <div class=\"cortex-widget__threads-header\">\n <div>\n <h2 class=\"cortex-widget__threads-title\">\n {{ 'translate_threads' | translate }}\n </h2>\n <p class=\"cortex-widget__threads-count\">\n {{\n 'translate_n_conversations' | translate: { count: chatService.threads()?.length ?? 0 }\n }}\n </p>\n </div>\n <button (click)=\"newChat()\" class=\"cortex-widget__new-chat-btn\">\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=\"cortex-widget__threads-list\">\n <!-- Threads loading skeleton -->\n @if (chatService.threads() === undefined) {\n @for (i of [1, 2, 3, 4]; track i) {\n <div class=\"cortex-widget__thread-skeleton\">\n <div class=\"cortex-skeleton cortex-widget__thread-skeleton-icon\"></div>\n <div class=\"cortex-widget__thread-skeleton-lines\">\n <div\n class=\"cortex-skeleton cortex-widget__thread-skeleton-line\"\n [style.width]=\"40 + i * 12 + '%'\"\n ></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=\"cortex-widget__thread-item\"\n [class.cortex-widget__thread-item--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n <!-- Thread icon -->\n <div\n class=\"cortex-widget__thread-icon\"\n [class.cortex-widget__thread-icon--active]=\"\n 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=\"cortex-widget__thread-info\">\n <div class=\"cortex-widget__thread-title-row\">\n <p\n class=\"cortex-widget__thread-title\"\n [class.cortex-widget__thread-title--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n {{ thread.title ?? ('translate_untitled' | translate) }}\n </p>\n\n @if (thread.isRunning) {\n <span\n class=\"cortex-widget__thread-running\"\n [class.cortex-widget__thread-running--active]=\"\n thread.id === chatService.selectedThread()?.id\n \"\n >\n <span class=\"cortex-widget__thread-running-dot\"></span>\n {{ 'translate_running' | translate }}\n </span>\n }\n </div>\n </div>\n\n <!-- Delete button -->\n <button\n (click)=\"$event.stopPropagation(); chatService.deleteThread(thread.id).subscribe()\"\n class=\"cortex-widget__thread-delete\"\n [class.cortex-widget__thread-delete--active]=\"\n 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=\"cortex-widget__thread-arrow\"\n [class.cortex-widget__thread-arrow--active]=\"\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=\"cortex-widget__threads-empty\">\n <div class=\"cortex-widget__threads-empty-icon\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__threads-empty-svg\"\n >\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=\"cortex-widget__threads-empty-title\">No threads yet</p>\n <p class=\"cortex-widget__threads-empty-subtitle\">Start a new conversation</p>\n </div>\n }\n }\n </div>\n </div>\n\n <!-- SCREEN 2: CHAT -->\n <div\n class=\"cortex-widget__screen\"\n [class.cortex-widget__screen--active]=\"screen() === 'chat'\"\n [class.cortex-widget__screen--right]=\"screen() !== 'chat'\"\n >\n <!-- Chat header -->\n <div class=\"cortex-widget__chat-header\">\n <!-- Back button -->\n <button (click)=\"goBack()\" class=\"cortex-widget__back-btn\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__back-icon\"\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=\"cortex-widget__chat-title-wrap\">\n <p class=\"cortex-widget__chat-title\">\n {{ chatService.selectedThread()?.title ?? ('translate_new_chat' | translate) }}\n </p>\n </div>\n\n <!-- Debug toggle -->\n @if (config().showDebugButton) {\n <button\n (click)=\"toggleDebugMode()\"\n class=\"cortex-widget__debug-btn\"\n [class.cortex-widget__debug-btn--on]=\"debugMode()\"\n [class.cortex-widget__debug-btn--off]=\"!debugMode()\"\n >\n {{ debugMode() ? ('translate_debug' | translate) : ('translate_normal' | translate) }}\n </button>\n }\n </div>\n\n <!-- Messages loading skeleton -->\n @if (chatService.isLoadingMessages() && !chatService.isAgentWorking()) {\n <div class=\"cortex-widget__messages-skeleton\">\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 13rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 9rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 16rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 18rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 12rem\"></div>\n </div>\n </div>\n <!-- User message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--user\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 11rem\"></div>\n </div>\n </div>\n <!-- Assistant message skeleton -->\n <div class=\"cortex-widget__msg-skel cortex-widget__msg-skel--assistant\">\n <div class=\"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant\">\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 14rem\"></div>\n <div class=\"cortex-skeleton cortex-widget__msg-skel-line\" style=\"width: 15rem\"></div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Messages area -->\n <cortex-message-list class=\"cortex-widget__messages\" [debugMode]=\"debugMode()\" />\n }\n\n <!-- Agent working indicator -->\n @if (chatService.isAgentWorking() && !chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__working\">\n <div class=\"cortex-widget__working-dots\">\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n <span class=\"cortex-working-dot\"></span>\n </div>\n <span class=\"cortex-widget__working-text\">{{ 'translate_thinking' | translate }}</span>\n </div>\n }\n\n <!-- Chat input (hidden during pending tool calls) -->\n @if (!chatService.hasPendingToolCalls()) {\n <div class=\"cortex-widget__input-area\">\n <div\n class=\"cortex-widget__input-box\"\n [class.cortex-widget__input-box--disabled]=\"chatService.isAgentWorking()\"\n [class.cortex-widget__input-box--enabled]=\"!chatService.isAgentWorking()\"\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=\"cortex-widget__textarea\"\n [class.cortex-widget__textarea--disabled]=\"chatService.isAgentWorking()\"\n ></textarea>\n @if (chatService.isAgentWorking()) {\n <!-- Stop button -->\n <button (click)=\"chatService.abort()\" class=\"cortex-stop-btn\">\n <!-- Pulsing ring -->\n <span class=\"cortex-stop-btn__ring\"></span>\n <!-- Stop icon (rounded square) -->\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n class=\"cortex-stop-btn__icon\"\n >\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=\"cortex-widget__send-btn\"\n [class.cortex-widget__send-btn--empty]=\"!text().trim()\"\n [class.cortex-widget__send-btn--ready]=\"!!text().trim()\"\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n class=\"cortex-widget__send-icon\"\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", styles: [".cortex-widget{display:block}.cortex-widget__container{width:100%;height:100%;position:relative;overflow:hidden}.cortex-widget__screen{position:absolute;inset:0;display:flex;flex-direction:column;transition:transform .3s ease-out}.cortex-widget__screen--active{transform:translate(0)}.cortex-widget__screen--left{transform:translate(-100%)}[dir=rtl] .cortex-widget__screen--left,.cortex-widget__screen--right{transform:translate(100%)}[dir=rtl] .cortex-widget__screen--right{transform:translate(-100%)}.cortex-widget__threads-header{flex-shrink:0;padding:1.25rem 1.25rem 1rem;display:flex;align-items:center;justify-content:space-between}.cortex-widget__threads-title{font-size:.9375rem;font-weight:600;color:#1e293b;letter-spacing:-.01em;margin:0}.cortex-widget__threads-count{font-size:.6875rem;color:#94a3b8;margin-top:.125rem;margin-bottom:0}.cortex-widget__new-chat-btn{display:inline-flex;align-items:center;gap:.375rem;font-size:.75rem;font-weight:500;color:#f1f5f9;background:#1e293b;padding:.375rem .75rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__new-chat-btn:hover{background:#334155}.cortex-widget__new-chat-btn:active{background:#0f172a}.cortex-widget__threads-list{flex:1;overflow-y:auto;padding:0 .75rem .75rem}.cortex-widget__thread-skeleton{display:flex;align-items:center;gap:.75rem;padding:.75rem;margin-bottom:.125rem}.cortex-widget__thread-skeleton-icon{flex-shrink:0;width:2rem;height:2rem}.cortex-widget__thread-skeleton-lines{flex:1;display:flex;flex-direction:column;gap:.375rem}.cortex-widget__thread-skeleton-line{height:.875rem}@keyframes cortex-skeleton-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.cortex-skeleton{background:linear-gradient(90deg,#e2e8f0,#f1f5f9,#e2e8f0 80%);background-size:200% 100%;animation:cortex-skeleton-shimmer 1.8s ease-in-out infinite;border-radius:6px}.cortex-widget__thread-item{width:100%;text-align:start;padding:.75rem;border-radius:.5rem;display:flex;align-items:center;gap:.75rem;transition:background-color .15s;cursor:pointer;margin-bottom:.125rem;border:0;background:transparent;color:#475569}.cortex-widget__thread-item:hover{background:#f1f5f9}.cortex-widget__thread-item:active{background:#e8ecf1}.cortex-widget__thread-item--active{background:#e2e8f0;color:#f1f5f9}.cortex-widget__thread-icon{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;font-size:.6875rem;font-weight:600;background:#e2e8f0;color:#64748b}[dir=rtl] .cortex-widget__thread-icon{transform:rotate(180deg)}.cortex-widget__thread-icon--active{background:#334155;color:#cbd5e1}.cortex-widget__thread-info{min-width:0;flex:1}.cortex-widget__thread-title-row{display:flex;align-items:center;gap:.5rem;min-width:0}.cortex-widget__thread-title{font-size:.8125rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.25;margin:0;color:#334155}.cortex-widget__thread-title--active{color:#f1f5f9}.cortex-widget__thread-running{flex-shrink:0;display:inline-flex;align-items:center;gap:.3125rem;padding:.2rem .45rem;border-radius:999px;background:#0e74901a;color:#0f766e;font-size:.625rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase}.cortex-widget__thread-running--active{background:#f1f5f929;color:#e2e8f0}.cortex-widget__thread-running-dot{width:.375rem;height:.375rem;border-radius:999px;background:currentColor;box-shadow:0 0 .45rem currentColor;animation:cortex-thread-running-pulse 1.4s ease-in-out infinite}@keyframes cortex-thread-running-pulse{0%,to{opacity:.45;transform:scale(.9)}50%{opacity:1;transform:scale(1)}}.cortex-widget__thread-delete{flex-shrink:0;opacity:0;width:1.75rem;height:1.75rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s;background:transparent;border:0;color:#94a3b8}.cortex-widget__thread-item:hover>.cortex-widget__thread-delete{opacity:1}.cortex-widget__thread-delete:hover{background:#e2e8f0}.cortex-widget__thread-delete--active:hover{background:#475569}.cortex-widget__thread-arrow{flex-shrink:0;transition:color .15s;color:#cbd5e1}[dir=rtl] .cortex-widget__thread-arrow{transform:rotate(180deg)}.cortex-widget__thread-item:hover>.cortex-widget__thread-arrow{color:#94a3b8}.cortex-widget__thread-arrow--active{color:#64748b}.cortex-widget__threads-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:4rem 0;text-align:center}.cortex-widget__threads-empty-icon{width:2.5rem;height:2.5rem;border-radius:.5rem;background:#e2e8f0;display:flex;align-items:center;justify-content:center;margin-bottom:.75rem}.cortex-widget__threads-empty-svg{color:#94a3b8}.cortex-widget__threads-empty-title{font-size:.8125rem;color:#94a3b8;font-weight:500;margin:0}.cortex-widget__threads-empty-subtitle{font-size:.6875rem;color:#a5afbd;margin-top:.25rem;margin-bottom:0}.cortex-widget__chat-header{flex-shrink:0;height:3rem;padding:0 1rem;display:flex;align-items:center;gap:.75rem;border-bottom:1px solid #e2e8f0;background:#fff}.cortex-widget__back-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.375rem;display:flex;align-items:center;justify-content:center;color:#94a3b8;background:transparent;border:0;cursor:pointer;transition:color .15s,background-color .15s}.cortex-widget__back-btn:hover{color:#475569;background:#f1f5f9}[dir=rtl] .cortex-widget__back-icon{transform:rotate(180deg)}.cortex-widget__chat-title-wrap{min-width:0;flex:1}.cortex-widget__chat-title{font-size:.8125rem;font-weight:500;color:#334155;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0}.cortex-widget__debug-btn{flex-shrink:0;font-size:.6875rem;font-weight:500;padding:.25rem .625rem;border-radius:.375rem;border:0;cursor:pointer;transition:background-color .15s}.cortex-widget__debug-btn--on{background:#fef3c7;color:#d97706}.cortex-widget__debug-btn--on:hover{background:#fde68a}.cortex-widget__debug-btn--off{background:#f1f5f9;color:#94a3b8}.cortex-widget__debug-btn--off:hover{background:#e2e8f0}.cortex-widget__messages-skeleton{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel{width:100%;display:flex;flex-direction:column}.cortex-widget__msg-skel--user{align-items:flex-end}.cortex-widget__msg-skel--assistant{align-items:flex-start}.cortex-widget__msg-skel-bubble{max-width:80%;padding:1rem;border-radius:1rem;border:1px solid #e2e8f0;display:flex;flex-direction:column;gap:.5rem}.cortex-widget__msg-skel-bubble--user{background:#f8fafc;border-bottom-right-radius:0}.cortex-widget__msg-skel-bubble--assistant{background:#f1f5f9;border-bottom-left-radius:0}.cortex-widget__msg-skel-line{height:.75rem}.cortex-widget__messages{flex:1;overflow:hidden}@keyframes cortex-working-slide-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}@keyframes cortex-dot-wave{0%,60%,to{transform:translateY(0) scale(1);opacity:.45}30%{transform:translateY(-5px) scale(1.2);opacity:1}}@keyframes cortex-working-shimmer{0%{background-position:-200% center}to{background-position:200% center}}.cortex-widget__working{flex-shrink:0;padding:.5rem 1rem;display:flex;align-items:center;gap:.5rem;animation:cortex-working-slide-in .25s ease-out both}.cortex-widget__working-dots{display:flex;align-items:center;gap:4px}.cortex-working-dot{display:block;width:6px;height:6px;border-radius:9999px;background:#22c55e;animation:cortex-dot-wave 1.4s ease-in-out infinite}.cortex-working-dot:nth-child(2){animation-delay:.15s}.cortex-working-dot:nth-child(3){animation-delay:.3s}.cortex-widget__working-text{font-size:.75rem;font-weight:500;letter-spacing:.01em;color:#16a34a}.cortex-widget__input-area{flex-shrink:0;padding:.75rem;background:#fff;border-top:1px solid #e2e8f0}.cortex-widget__input-box{display:flex;align-items:flex-end;gap:.5rem;border-radius:.75rem;border:1px solid #e2e8f0;padding:.375rem;transition:border-color .15s,background-color .15s}.cortex-widget__input-box--disabled{background:#f1f5f9}.cortex-widget__input-box--enabled{background:#f8fafc}.cortex-widget__input-box--enabled:focus-within{border-color:#cbd5e1;background:#fff}.cortex-widget__textarea{flex:1;background:transparent;resize:none;border:0;outline:none;font-size:.8125rem;padding:.375rem .5rem;min-height:28px;max-height:120px;line-height:1.375;color:#334155}.cortex-widget__textarea::placeholder{color:#a5afbd}.cortex-widget__textarea--disabled{color:#94a3b8;cursor:not-allowed}.cortex-widget__textarea:disabled{cursor:not-allowed;border:0}@keyframes cortex-stop-pulse-ring{0%{opacity:.45;transform:scale(1)}50%{opacity:.15;transform:scale(1.12)}to{opacity:.45;transform:scale(1)}}@keyframes cortex-stop-fade-in{0%{opacity:0;transform:scale(.7)}to{opacity:1;transform:scale(1)}}.cortex-stop-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;cursor:pointer;position:relative;background:#e11d48;color:#fff;border:0;animation:cortex-stop-fade-in .2s ease-out both;transition:background .15s ease}.cortex-stop-btn:hover{background:#be123c}.cortex-stop-btn:active{transform:scale(.92)}.cortex-stop-btn__ring{position:absolute;inset:0;border-radius:.5rem;background:#e11d48;animation:cortex-stop-pulse-ring 2s ease-in-out infinite;pointer-events:none}.cortex-stop-btn__icon{position:relative;z-index:1}.cortex-widget__send-btn{flex-shrink:0;width:2rem;height:2rem;border-radius:.5rem;display:flex;align-items:center;justify-content:center;border:0;transition:background-color .15s}.cortex-widget__send-btn--empty{background:#e2e8f0;color:#94a3b8}.cortex-widget__send-btn--ready{background:#1e293b;color:#fff;cursor:pointer}.cortex-widget__send-btn--ready:hover{background:#334155}[dir=rtl] .cortex-widget__send-icon{transform:rotate(180deg)}\n"] }]
|
|
1683
2000
|
}], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }], text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }, { type: i0.Output, args: ["textChange"] }] } });
|
|
1684
2001
|
|
|
1685
2002
|
/*
|