@dataclouder/ngx-agent-cards 0.1.0 → 0.1.2
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/fesm2022/dataclouder-ngx-agent-cards.mjs +178 -69
- package/fesm2022/dataclouder-ngx-agent-cards.mjs.map +1 -1
- package/lib/components/chat-container/chat-container.component.d.ts +5 -3
- package/lib/components/chat-container/chat-footer/chat-footer.component.d.ts +15 -0
- package/lib/components/chat-container/chat-messages-list/chat-messages-list.component.d.ts +3 -3
- package/lib/components/chat-container/chat-messages-list/message-orchestrator/message-orchestrator.component.d.ts +1 -1
- package/lib/components/{chat-settings → chat-container/chat-settings}/dc-conversation-userchat-settings.component.d.ts +1 -1
- package/lib/components/dc-agent-card-details/dc-agent-card-details.component.d.ts +0 -3
- package/lib/models/agent.models.d.ts +17 -9
- package/lib/models/user-data-exchange.d.ts +8 -1
- package/lib/services/conversation.service.d.ts +15 -4
- package/lib/services/evaluation.service.d.ts +2 -3
- package/lib/services/message-processing.service.d.ts +6 -2
- package/package.json +1 -1
- package/public-api.d.ts +1 -1
- package/README.md +0 -324
- /package/lib/{components → utils/icons}/extraction.regex.d.ts +0 -0
- /package/lib/{components → utils}/icons/icon-map.d.ts +0 -0
- /package/lib/{components → utils}/icons/icons.component.d.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable, inject, Pipe, input, output, Input, Component, signal, computed, ChangeDetectorRef, DestroyRef,
|
|
2
|
+
import { InjectionToken, Injectable, inject, Pipe, input, output, Input, Component, signal, effect, computed, ChangeDetectorRef, DestroyRef, ChangeDetectionStrategy, ElementRef, ViewChild, ViewChildren } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/common';
|
|
4
4
|
import { CommonModule, DatePipe, DecimalPipe, NgComponentOutlet } from '@angular/common';
|
|
5
5
|
import { DynamicDialogRef, DialogService, DynamicDialogConfig, DynamicDialogModule } from 'primeng/dynamicdialog';
|
|
@@ -14,6 +14,7 @@ import * as i3 from 'primeng/textarea';
|
|
|
14
14
|
import { TextareaModule } from 'primeng/textarea';
|
|
15
15
|
import * as i2$1 from 'primeng/button';
|
|
16
16
|
import { ButtonModule } from 'primeng/button';
|
|
17
|
+
import { nanoid } from 'nanoid';
|
|
17
18
|
import { AudioSpeed as AudioSpeed$1, TOAST_ALERTS_TOKEN, PaginationBase, DCFilterBarComponent, QuickTableComponent } from '@dataclouder/ngx-core';
|
|
18
19
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
19
20
|
import { Subject, fromEvent, filter } from 'rxjs';
|
|
@@ -980,16 +981,22 @@ function removeAllEmojis(text) {
|
|
|
980
981
|
}
|
|
981
982
|
|
|
982
983
|
class MessageProcessingService {
|
|
983
|
-
constructor() { }
|
|
984
984
|
// Process message for display
|
|
985
|
-
processMessage(message, conversationSettings) {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
processedMessage
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
985
|
+
processMessage(message, conversationSettings, extraData = {}) {
|
|
986
|
+
let processedMessage = { ...message };
|
|
987
|
+
// Add ID if not present
|
|
988
|
+
if (!processedMessage.messageId) {
|
|
989
|
+
processedMessage.messageId = nanoid();
|
|
990
|
+
}
|
|
991
|
+
// Add images and default voice
|
|
992
|
+
if (message.role === ChatRole.User && extraData.userImg) {
|
|
993
|
+
processedMessage.imgUrl = extraData.userImg;
|
|
994
|
+
}
|
|
995
|
+
else if (message.role === ChatRole.Assistant && extraData.assistantImg) {
|
|
996
|
+
const defaultVoice = this.getVoice(conversationSettings.voice);
|
|
997
|
+
processedMessage.voice = defaultVoice;
|
|
998
|
+
processedMessage.imgUrl = extraData.assistantImg;
|
|
999
|
+
}
|
|
993
1000
|
// Process based on text engine
|
|
994
1001
|
if (conversationSettings.textEngine === TextEngines.MarkdownMultiMessages) {
|
|
995
1002
|
this.processMultiMessages(processedMessage, conversationSettings);
|
|
@@ -1001,8 +1008,7 @@ class MessageProcessingService {
|
|
|
1001
1008
|
const content = this.subsItalicsByTag(processedMessage.content, conversationSettings.secondaryVoice);
|
|
1002
1009
|
processedMessage.ssml = '<speak>' + content + '</speak>';
|
|
1003
1010
|
}
|
|
1004
|
-
|
|
1005
|
-
return { ...message, ...processedMessage };
|
|
1011
|
+
return processedMessage;
|
|
1006
1012
|
}
|
|
1007
1013
|
// Process multi-messages from markdown
|
|
1008
1014
|
processMultiMessages(message, settings) {
|
|
@@ -1063,7 +1069,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1063
1069
|
args: [{
|
|
1064
1070
|
providedIn: 'root',
|
|
1065
1071
|
}]
|
|
1066
|
-
}]
|
|
1072
|
+
}] });
|
|
1067
1073
|
|
|
1068
1074
|
function matchTranscription(originalText, transcription) {
|
|
1069
1075
|
const result = [];
|
|
@@ -1132,19 +1138,42 @@ class ConversationService {
|
|
|
1132
1138
|
this.messageProcessingService = inject(MessageProcessingService);
|
|
1133
1139
|
this.conversationBuilder = inject(DCConversationPromptBuilderService);
|
|
1134
1140
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
1135
|
-
// Signals
|
|
1141
|
+
// State Signals
|
|
1136
1142
|
this.messagesSignal = signal([]);
|
|
1137
1143
|
this.isThinkingSignal = signal(false);
|
|
1138
1144
|
this.conversationSettingsSignal = signal(null);
|
|
1139
1145
|
this.isDestroyedSignal = signal(false);
|
|
1146
|
+
this.micStatusSignal = signal('ready');
|
|
1147
|
+
this.currentAudioStatus = signal(null);
|
|
1148
|
+
// Var State
|
|
1149
|
+
this.avatarImages = {
|
|
1150
|
+
userImg: 'assets/defaults/avatar_user.png',
|
|
1151
|
+
assistantImg: 'assets/defaults/avatar_ai.webp',
|
|
1152
|
+
};
|
|
1140
1153
|
}
|
|
1141
|
-
// Get messages as a signal
|
|
1142
1154
|
getMessagesSignal() {
|
|
1143
1155
|
return this.messagesSignal;
|
|
1144
1156
|
}
|
|
1145
1157
|
// Add message to conversation
|
|
1146
1158
|
addMessage(message) {
|
|
1147
1159
|
this.messagesSignal.update((messages) => [...messages, message]);
|
|
1160
|
+
console.log('Message added:', this.messagesSignal());
|
|
1161
|
+
return message.messageId;
|
|
1162
|
+
}
|
|
1163
|
+
// Update message by ID
|
|
1164
|
+
updateMessage(messageId, updatedMessage) {
|
|
1165
|
+
let found = false;
|
|
1166
|
+
this.messagesSignal.update((messages) => {
|
|
1167
|
+
return messages.map((message) => {
|
|
1168
|
+
if (message.messageId === messageId) {
|
|
1169
|
+
found = true;
|
|
1170
|
+
// Create a new message object with the updated properties
|
|
1171
|
+
return { ...message, ...updatedMessage };
|
|
1172
|
+
}
|
|
1173
|
+
return message;
|
|
1174
|
+
});
|
|
1175
|
+
});
|
|
1176
|
+
return found;
|
|
1148
1177
|
}
|
|
1149
1178
|
// Get thinking state as a signal
|
|
1150
1179
|
isThinking() {
|
|
@@ -1154,8 +1183,10 @@ class ConversationService {
|
|
|
1154
1183
|
setDestroyed(value) {
|
|
1155
1184
|
this.isDestroyedSignal.set(value);
|
|
1156
1185
|
}
|
|
1157
|
-
setupConversationWithAgentCard(agentCard) {
|
|
1158
|
-
|
|
1186
|
+
setupConversationWithAgentCard(agentCard, parseDict = null) {
|
|
1187
|
+
// Set user AI avatar image
|
|
1188
|
+
this.avatarImages.assistantImg = agentCard?.assets.image?.url || this.avatarImages.assistantImg;
|
|
1189
|
+
const conversationSettings = this.conversationBuilder.buildConversationSettings(agentCard, parseDict);
|
|
1159
1190
|
this.conversationSettingsSignal.set(conversationSettings);
|
|
1160
1191
|
}
|
|
1161
1192
|
async initConversationWithSettings(conversationSettings) {
|
|
@@ -1163,6 +1194,9 @@ class ConversationService {
|
|
|
1163
1194
|
await this.initConversation();
|
|
1164
1195
|
}
|
|
1165
1196
|
async initConversation() {
|
|
1197
|
+
// Set user avatar images
|
|
1198
|
+
this.avatarImages.userImg = this.userDataExchange.getUserDataExchange().imgUrl;
|
|
1199
|
+
console.log(this.avatarImages);
|
|
1166
1200
|
const conversationSettings = this.conversationSettingsSignal();
|
|
1167
1201
|
for (const i in conversationSettings.messages) {
|
|
1168
1202
|
conversationSettings.messages[i].messageId = 'msg_' + i;
|
|
@@ -1172,7 +1206,7 @@ class ConversationService {
|
|
|
1172
1206
|
this.messagesSignal.set(conversationSettings?.messages || []);
|
|
1173
1207
|
if (firstAssistantMsg) {
|
|
1174
1208
|
// Process the first assistant message
|
|
1175
|
-
const processedMessage = this.messageProcessingService.processMessage(firstAssistantMsg, this.conversationSettingsSignal());
|
|
1209
|
+
const processedMessage = this.messageProcessingService.processMessage(firstAssistantMsg, this.conversationSettingsSignal(), this.avatarImages);
|
|
1176
1210
|
// Find the index of the message with the matching ID
|
|
1177
1211
|
const messageIndex = conversationSettings.messages.findIndex((message) => message.messageId === firstAssistantMsg.messageId);
|
|
1178
1212
|
// If found, replace the message at that index
|
|
@@ -1186,17 +1220,23 @@ class ConversationService {
|
|
|
1186
1220
|
}
|
|
1187
1221
|
}
|
|
1188
1222
|
// Initialize conversation
|
|
1189
|
-
async initConversationWithAgentCard(agentCard) {
|
|
1190
|
-
this.setupConversationWithAgentCard(agentCard);
|
|
1223
|
+
async initConversationWithAgentCard(agentCard, parseDict = null) {
|
|
1224
|
+
this.setupConversationWithAgentCard(agentCard, parseDict);
|
|
1191
1225
|
await this.initConversation();
|
|
1192
1226
|
}
|
|
1193
1227
|
// Send user message
|
|
1194
|
-
async sendUserMessage(message) {
|
|
1228
|
+
async sendUserMessage(message, updateId = null) {
|
|
1195
1229
|
if (this.isThinkingSignal()) {
|
|
1196
1230
|
return;
|
|
1197
1231
|
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1232
|
+
if (updateId) {
|
|
1233
|
+
this.updateMessage(updateId, message);
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
// Add message to conversation
|
|
1237
|
+
const processedMessage = this.messageProcessingService.processMessage(message, this.conversationSettingsSignal(), this.avatarImages);
|
|
1238
|
+
this.addMessage(processedMessage);
|
|
1239
|
+
}
|
|
1200
1240
|
// Set thinking state
|
|
1201
1241
|
this.isThinkingSignal.set(true);
|
|
1202
1242
|
try {
|
|
@@ -1238,7 +1278,7 @@ class ConversationService {
|
|
|
1238
1278
|
throw new Error('No message returned from AI');
|
|
1239
1279
|
}
|
|
1240
1280
|
// Process response
|
|
1241
|
-
const newMessage = this.messageProcessingService.processMessage(response, conversationSettings);
|
|
1281
|
+
const newMessage = this.messageProcessingService.processMessage(response, conversationSettings, this.avatarImages);
|
|
1242
1282
|
// Add to messages
|
|
1243
1283
|
this.addMessage(newMessage);
|
|
1244
1284
|
this.isThinkingSignal.set(false);
|
|
@@ -1278,8 +1318,11 @@ function extractJsonFromResponse(content) {
|
|
|
1278
1318
|
|
|
1279
1319
|
class EvaluationService {
|
|
1280
1320
|
constructor() {
|
|
1321
|
+
// Services
|
|
1281
1322
|
this.agentCardService = inject(CONVERSATION_AI_TOKEN);
|
|
1282
|
-
this.
|
|
1323
|
+
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1324
|
+
// Signals
|
|
1325
|
+
this.scoreSignal = signal(0);
|
|
1283
1326
|
this.evaluationResultSignal = signal(null);
|
|
1284
1327
|
}
|
|
1285
1328
|
// Get score as a signal
|
|
@@ -1301,9 +1344,7 @@ class EvaluationService {
|
|
|
1301
1344
|
return;
|
|
1302
1345
|
}
|
|
1303
1346
|
// Format conversation for evaluation
|
|
1304
|
-
const conversationMessagesString = conversationMessages
|
|
1305
|
-
.map((message) => `${message.role}: ${message.content}`)
|
|
1306
|
-
.join('\n');
|
|
1347
|
+
const conversationMessagesString = conversationMessages.map((message) => `${message.role}: ${message.content}`).join('\n');
|
|
1307
1348
|
// Create evaluation prompt
|
|
1308
1349
|
const instructions = `
|
|
1309
1350
|
Please replay to this task:
|
|
@@ -1315,20 +1356,26 @@ and give the response in next JSON format.
|
|
|
1315
1356
|
`;
|
|
1316
1357
|
// Send evaluation request
|
|
1317
1358
|
const evaluationMessages = [{ content: instructions, role: ChatRole.User }];
|
|
1359
|
+
// Not sure what strategy use, if works types should be definied in definitions, generarally response will be score, and feedback.
|
|
1318
1360
|
const response = await this.agentCardService.callChatCompletion({ messages: evaluationMessages });
|
|
1319
1361
|
// Extract JSON from response
|
|
1320
1362
|
const jsonData = extractJsonFromResponse(response.content);
|
|
1321
1363
|
this.evaluationResultSignal.set(jsonData);
|
|
1364
|
+
this.toastService.info({
|
|
1365
|
+
title: 'Score ' + jsonData.score,
|
|
1366
|
+
subtitle: `Added ${jsonData.feedback} points`,
|
|
1367
|
+
});
|
|
1322
1368
|
// Update score if available
|
|
1323
1369
|
if (jsonData.score) {
|
|
1324
1370
|
if (jsonData.score <= 3) {
|
|
1325
1371
|
this.updateScore(jsonData.score * 10);
|
|
1326
1372
|
}
|
|
1327
1373
|
}
|
|
1374
|
+
return jsonData;
|
|
1328
1375
|
}
|
|
1329
1376
|
// Update score with limits
|
|
1330
1377
|
updateScore(additionalScore) {
|
|
1331
|
-
this.scoreSignal.update(currentScore => {
|
|
1378
|
+
this.scoreSignal.update((currentScore) => {
|
|
1332
1379
|
const newScore = currentScore + additionalScore;
|
|
1333
1380
|
return newScore > 100 ? 100 : newScore;
|
|
1334
1381
|
});
|
|
@@ -1345,7 +1392,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1345
1392
|
args: [{
|
|
1346
1393
|
providedIn: 'root',
|
|
1347
1394
|
}]
|
|
1348
|
-
}]
|
|
1395
|
+
}] });
|
|
1349
1396
|
|
|
1350
1397
|
class ChatFooterComponent {
|
|
1351
1398
|
constructor() {
|
|
@@ -1363,9 +1410,31 @@ class ChatFooterComponent {
|
|
|
1363
1410
|
// readonly micFinishedEvent = output<any>();
|
|
1364
1411
|
this.isGettingTranscription = false;
|
|
1365
1412
|
this.isUserTalking = false;
|
|
1413
|
+
this.micStatus = '';
|
|
1414
|
+
// Signal to control mic resumption
|
|
1415
|
+
this.shouldResumeMic = signal(false);
|
|
1366
1416
|
this.chatInputControl = new FormControl();
|
|
1367
1417
|
// Get score from evaluation service
|
|
1368
1418
|
this.score = this.evaluationService.getScore();
|
|
1419
|
+
// Watch for audio completion and set the shouldResumeMic signal
|
|
1420
|
+
effect(() => {
|
|
1421
|
+
const audioStatus = this.conversationService.currentAudioStatus();
|
|
1422
|
+
// If audio has completed playing and mic is in paused state, resume recording
|
|
1423
|
+
if (audioStatus?.completed && this.micStatus === 'paused') {
|
|
1424
|
+
console.log('Audio playback completed, resuming mic recording');
|
|
1425
|
+
this.shouldResumeMic.set(true);
|
|
1426
|
+
// Reset after a short delay to avoid continuous triggering
|
|
1427
|
+
setTimeout(() => {
|
|
1428
|
+
this.shouldResumeMic.set(false);
|
|
1429
|
+
}, 100);
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Method used by the template to determine if the mic should continue listening
|
|
1435
|
+
*/
|
|
1436
|
+
shouldContinueListening() {
|
|
1437
|
+
return this.shouldResumeMic();
|
|
1369
1438
|
}
|
|
1370
1439
|
/**
|
|
1371
1440
|
* Sets the input text in the textarea
|
|
@@ -1382,6 +1451,7 @@ class ChatFooterComponent {
|
|
|
1382
1451
|
micFinished(eventBlob) {
|
|
1383
1452
|
// this.micFinishedEvent.emit(eventBlob);
|
|
1384
1453
|
}
|
|
1454
|
+
// how to handle status audio finished? this.conversationService.currentAudioStatus.
|
|
1385
1455
|
/**
|
|
1386
1456
|
* Sends the user message
|
|
1387
1457
|
*/
|
|
@@ -1409,13 +1479,24 @@ class ChatFooterComponent {
|
|
|
1409
1479
|
async evaluateConversation() {
|
|
1410
1480
|
const messages = this.conversationService.getMessagesSignal()();
|
|
1411
1481
|
if (this.evaluatorAgentCard()) {
|
|
1412
|
-
await this.evaluationService.evaluateConversation(messages, this.evaluatorAgentCard());
|
|
1482
|
+
const data = await this.evaluationService.evaluateConversation(messages, this.evaluatorAgentCard());
|
|
1483
|
+
console.log(data);
|
|
1413
1484
|
}
|
|
1414
1485
|
}
|
|
1415
1486
|
handleAudioRecorded(event) {
|
|
1416
1487
|
console.log(event);
|
|
1417
1488
|
this.onMicFinished(event.blob);
|
|
1418
1489
|
}
|
|
1490
|
+
/**
|
|
1491
|
+
* Handles the mic status changed event
|
|
1492
|
+
* @param event The status event from the mic component
|
|
1493
|
+
*/
|
|
1494
|
+
handleMicStatusChanged(event) {
|
|
1495
|
+
console.log('Mic status changed:', event);
|
|
1496
|
+
this.micStatus = event.status;
|
|
1497
|
+
// Update isUserTalking based on the status
|
|
1498
|
+
this.isUserTalking = event.status === 'recording';
|
|
1499
|
+
}
|
|
1419
1500
|
async onMicFinished(eventBlob) {
|
|
1420
1501
|
if (!(eventBlob instanceof Blob)) {
|
|
1421
1502
|
return;
|
|
@@ -1423,32 +1504,37 @@ class ChatFooterComponent {
|
|
|
1423
1504
|
this.isUserTalking = false;
|
|
1424
1505
|
this.isGettingTranscription = true;
|
|
1425
1506
|
try {
|
|
1426
|
-
// Get transcription from audio
|
|
1427
|
-
const transcription = await this.agentCardService.getAudioTranscriptions(eventBlob, null);
|
|
1428
1507
|
const message = {
|
|
1429
1508
|
content: '',
|
|
1430
1509
|
role: ChatRole.User,
|
|
1431
1510
|
audioUrl: URL.createObjectURL(eventBlob),
|
|
1511
|
+
isLoading: true,
|
|
1512
|
+
};
|
|
1513
|
+
const messageId = this.conversationService.addMessage(message);
|
|
1514
|
+
// Get transcription from audio
|
|
1515
|
+
const transcription = await this.agentCardService.getAudioTranscriptions(eventBlob, null);
|
|
1516
|
+
// Create updated message with transcription and isLoading set to false
|
|
1517
|
+
const updatedMessage = {
|
|
1518
|
+
...message,
|
|
1519
|
+
content: transcription ? transcription.text : '',
|
|
1520
|
+
transcription: transcription || undefined,
|
|
1521
|
+
isLoading: false,
|
|
1432
1522
|
};
|
|
1433
|
-
if (transcription) {
|
|
1434
|
-
message.content = transcription.text;
|
|
1435
|
-
message.transcription = transcription;
|
|
1436
|
-
}
|
|
1437
1523
|
// Send message to conversation
|
|
1438
1524
|
// The evaluation will happen automatically in the conversation service
|
|
1439
|
-
await this.conversationService.sendUserMessage(
|
|
1525
|
+
await this.conversationService.sendUserMessage(updatedMessage, messageId);
|
|
1440
1526
|
}
|
|
1441
1527
|
finally {
|
|
1442
1528
|
this.isGettingTranscription = false;
|
|
1443
1529
|
}
|
|
1444
1530
|
}
|
|
1445
1531
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1446
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
1532
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", isSignal: true, isRequired: false, transformFunction: null }, evaluatorAgentCard: { classPropertyName: "evaluatorAgentCard", publicName: "evaluatorAgentCard", isSignal: true, isRequired: false, transformFunction: null }, micSettings: { classPropertyName: "micSettings", publicName: "micSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", textInputChanged: "textInputChanged" }, ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <app-mic-vad\n (audioRecorded)=\"handleAudioRecorded($event)\"\n (statusChanged)=\"handleMicStatusChanged($event)\"\n [continueListening]=\"shouldContinueListening()\" />\n <!-- <dc-mic\n style=\"display: flex; align-items: center\"\n (onInterpretedText)=\"setInputText($event)\"\n (onFinished)=\"micFinished($event)\"\n [micSettings]=\"micSettings()\"></dc-mic> -->\n\n <textarea pTextarea [formControl]=\"chatInputControl\" (keyup.enter)=\"sendUserMessage()\" rows=\"1\"></textarea>\n\n <p-button (click)=\"sendUserMessage()\" [disabled]=\"isAIThinking() || !chatInputControl.value\" label=\"Enviar\" [rounded]=\"true\" />\n </div>\n\n @if(evaluatorAgentCard()) {\n <div>\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n </div>\n }\n</div>\n", styles: [".progress-input{padding:10px;background-color:#f5f5f545;border-top:1px solid #b1a8a8}.progress-input .input-container{display:flex;align-items:center;margin-bottom:5px}.progress-input .input-container textarea{flex:1;resize:none;margin:0 10px}.progress-input .input-container .send-button{background-color:#007bff;color:#fff;border:none;border-radius:4px;padding:8px 15px;cursor:pointer}.progress-input .input-container .send-button:disabled{background-color:#ccc;cursor:not-allowed}.progress-input .input-container .send-button:hover:not(:disabled){background-color:#0069d9}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: MicVadComponent, selector: "app-mic-vad", inputs: ["continueListening"], outputs: ["statusChanged", "audioRecorded", "error"] }] }); }
|
|
1447
1533
|
}
|
|
1448
1534
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatFooterComponent, decorators: [{
|
|
1449
1535
|
type: Component,
|
|
1450
|
-
args: [{ selector: 'dc-chat-footer', standalone: true, imports: [ReactiveFormsModule, ProgressBarModule, TextareaModule, ButtonModule, MicVadComponent], template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <app-mic-vad
|
|
1451
|
-
}] });
|
|
1536
|
+
args: [{ selector: 'dc-chat-footer', standalone: true, imports: [ReactiveFormsModule, ProgressBarModule, TextareaModule, ButtonModule, MicVadComponent], template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <app-mic-vad\n (audioRecorded)=\"handleAudioRecorded($event)\"\n (statusChanged)=\"handleMicStatusChanged($event)\"\n [continueListening]=\"shouldContinueListening()\" />\n <!-- <dc-mic\n style=\"display: flex; align-items: center\"\n (onInterpretedText)=\"setInputText($event)\"\n (onFinished)=\"micFinished($event)\"\n [micSettings]=\"micSettings()\"></dc-mic> -->\n\n <textarea pTextarea [formControl]=\"chatInputControl\" (keyup.enter)=\"sendUserMessage()\" rows=\"1\"></textarea>\n\n <p-button (click)=\"sendUserMessage()\" [disabled]=\"isAIThinking() || !chatInputControl.value\" label=\"Enviar\" [rounded]=\"true\" />\n </div>\n\n @if(evaluatorAgentCard()) {\n <div>\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n </div>\n }\n</div>\n", styles: [".progress-input{padding:10px;background-color:#f5f5f545;border-top:1px solid #b1a8a8}.progress-input .input-container{display:flex;align-items:center;margin-bottom:5px}.progress-input .input-container textarea{flex:1;resize:none;margin:0 10px}.progress-input .input-container .send-button{background-color:#007bff;color:#fff;border:none;border-radius:4px;padding:8px 15px;cursor:pointer}.progress-input .input-container .send-button:disabled{background-color:#ccc;cursor:not-allowed}.progress-input .input-container .send-button:hover:not(:disabled){background-color:#0069d9}\n"] }]
|
|
1537
|
+
}], ctorParameters: () => [] });
|
|
1452
1538
|
|
|
1453
1539
|
const ICONS = {
|
|
1454
1540
|
chat: `<svg viewBox="0 0 24 24" fill="currentColor">
|
|
@@ -1775,11 +1861,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1775
1861
|
|
|
1776
1862
|
class MessageOrchestratorComponent {
|
|
1777
1863
|
constructor() {
|
|
1778
|
-
this.agentCardService = inject(CONVERSATION_AI_TOKEN);
|
|
1779
1864
|
this.conversationService = inject(ConversationService);
|
|
1780
1865
|
this.messages = input.required();
|
|
1781
1866
|
this.messageRole = input.required();
|
|
1782
1867
|
this.messagesSignal = signal([]);
|
|
1868
|
+
// Effect to update messagesSignal when input messages change
|
|
1869
|
+
this.messagesEffect = effect(() => {
|
|
1870
|
+
// Get the latest messages from the input
|
|
1871
|
+
const currentMessages = this.messages();
|
|
1872
|
+
if (currentMessages && currentMessages.length > 0) {
|
|
1873
|
+
// Update our internal signal with a new array reference
|
|
1874
|
+
this.messagesSignal.set([...currentMessages]);
|
|
1875
|
+
}
|
|
1876
|
+
});
|
|
1783
1877
|
this.playAudio = output();
|
|
1784
1878
|
this.audioCompleted = output();
|
|
1785
1879
|
// Audio queue management
|
|
@@ -1868,6 +1962,7 @@ class MessageOrchestratorComponent {
|
|
|
1868
1962
|
onAudioCompleted(message) {
|
|
1869
1963
|
// Forward the event
|
|
1870
1964
|
this.audioCompleted.emit(message);
|
|
1965
|
+
this.conversationService.currentAudioStatus.set({ message, completed: true });
|
|
1871
1966
|
// Reset current playing index
|
|
1872
1967
|
this.currentPlayingIndex = null;
|
|
1873
1968
|
// If there are more messages in the queue, process the next one
|
|
@@ -1902,8 +1997,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1902
1997
|
|
|
1903
1998
|
class ChatMessageComponent {
|
|
1904
1999
|
constructor() {
|
|
2000
|
+
// Inputs
|
|
1905
2001
|
this.chatMessage = input.required();
|
|
1906
2002
|
this.chatUserSettings = input(null);
|
|
2003
|
+
// Signal States
|
|
1907
2004
|
this.audioMessage = signal(null);
|
|
1908
2005
|
// Computed properties for easier access to signal values
|
|
1909
2006
|
this.hasMultiMessages = computed(() => !!this.chatMessage()?.multiMessages);
|
|
@@ -1931,37 +2028,38 @@ class ChatMessageComponent {
|
|
|
1931
2028
|
});
|
|
1932
2029
|
}
|
|
1933
2030
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1934
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessageComponent, isStandalone: true, selector: "dc-chat-message", inputs: { chatMessage: { classPropertyName: "chatMessage", publicName: "chatMessage", isSignal: true, isRequired: true, transformFunction: null }, chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar for assistant messages -->\n\n @if (!isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar\">\n <img src=\"
|
|
2031
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessageComponent, isStandalone: true, selector: "dc-chat-message", inputs: { chatMessage: { classPropertyName: "chatMessage", publicName: "chatMessage", isSignal: true, isRequired: true, transformFunction: null }, chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar for assistant messages -->\n\n @if (!isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar\">\n <img [src]=\"chatMessage().imgUrl\" alt=\"AI\" class=\"avatar-image\" />\n </div>\n </div>\n }\n\n <!-- Message content -->\n <div class=\"message-bubble\">\n @if (hasMultiMessages()) {\n <dc-message-orchestrator [messages]=\"multiMessages()\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n } @else {\n <dc-message-orchestrator [messages]=\"[audioMessage()]\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n }\n\n <!-- Translation if available -->\n @if (messageTranslation()) {\n <div class=\"translation\">\n <hr class=\"divider\" />\n {{ messageTranslation() }}\n </div>\n }\n </div>\n\n <!-- Avatar for user messages -->\n @if (isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar user-avatar\">\n <img [src]=\"chatMessage().imgUrl\" alt=\"User\" class=\"avatar-image\" />\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;margin-bottom:16px}.message-wrapper{display:flex;width:100%;margin-bottom:12px}.message-container{display:flex;max-width:85%;line-height:1.5}.user-message{justify-content:flex-end}.user-message .message-container{flex-direction:row}.user-message .message-bubble{background-color:#0d5878;color:#fff;border-radius:18px 18px 0;margin-left:8px}.assistant-message{justify-content:flex-start}.assistant-message .message-container{flex-direction:row}.assistant-message .message-bubble{background-color:#f0f0f0;color:#333;border-radius:18px 18px 18px 0;margin-left:8px}.message-bubble{padding:12px 16px;box-shadow:0 1px 2px #0000001a;max-width:calc(100% - 50px);word-wrap:break-word;overflow-wrap:break-word;word-break:break-word;hyphens:auto;min-width:0}.avatar-container{display:flex;align-items:flex-end}.avatar{width:36px;height:36px;border-radius:50%;background-color:#0d5878;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:14px;overflow:hidden}.avatar-image{width:100%;height:100%;object-fit:cover}.user-avatar{background-color:#ffa77e}::ng-deep .em{color:inherit;font-style:italic}::ng-deep .strong{font-weight:700;color:inherit}::ng-deep .em_strong{font-weight:700;font-style:italic;color:inherit}.translation{margin-top:8px;font-size:small;line-height:1.6;color:#393744;font-style:italic}.divider{margin:.5rem 40px;border-top:1px solid #ffa77e}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MessageOrchestratorComponent, selector: "dc-message-orchestrator", inputs: ["messages", "messageRole"], outputs: ["playAudio", "audioCompleted"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1935
2032
|
}
|
|
1936
2033
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessageComponent, decorators: [{
|
|
1937
2034
|
type: Component,
|
|
1938
|
-
args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, MessageOrchestratorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar for assistant messages -->\n\n @if (!isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar\">\n <img src=\"
|
|
2035
|
+
args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, MessageOrchestratorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar for assistant messages -->\n\n @if (!isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar\">\n <img [src]=\"chatMessage().imgUrl\" alt=\"AI\" class=\"avatar-image\" />\n </div>\n </div>\n }\n\n <!-- Message content -->\n <div class=\"message-bubble\">\n @if (hasMultiMessages()) {\n <dc-message-orchestrator [messages]=\"multiMessages()\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n } @else {\n <dc-message-orchestrator [messages]=\"[audioMessage()]\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n }\n\n <!-- Translation if available -->\n @if (messageTranslation()) {\n <div class=\"translation\">\n <hr class=\"divider\" />\n {{ messageTranslation() }}\n </div>\n }\n </div>\n\n <!-- Avatar for user messages -->\n @if (isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar user-avatar\">\n <img [src]=\"chatMessage().imgUrl\" alt=\"User\" class=\"avatar-image\" />\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;margin-bottom:16px}.message-wrapper{display:flex;width:100%;margin-bottom:12px}.message-container{display:flex;max-width:85%;line-height:1.5}.user-message{justify-content:flex-end}.user-message .message-container{flex-direction:row}.user-message .message-bubble{background-color:#0d5878;color:#fff;border-radius:18px 18px 0;margin-left:8px}.assistant-message{justify-content:flex-start}.assistant-message .message-container{flex-direction:row}.assistant-message .message-bubble{background-color:#f0f0f0;color:#333;border-radius:18px 18px 18px 0;margin-left:8px}.message-bubble{padding:12px 16px;box-shadow:0 1px 2px #0000001a;max-width:calc(100% - 50px);word-wrap:break-word;overflow-wrap:break-word;word-break:break-word;hyphens:auto;min-width:0}.avatar-container{display:flex;align-items:flex-end}.avatar{width:36px;height:36px;border-radius:50%;background-color:#0d5878;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:14px;overflow:hidden}.avatar-image{width:100%;height:100%;object-fit:cover}.user-avatar{background-color:#ffa77e}::ng-deep .em{color:inherit;font-style:italic}::ng-deep .strong{font-weight:700;color:inherit}::ng-deep .em_strong{font-weight:700;font-style:italic;color:inherit}.translation{margin-top:8px;font-size:small;line-height:1.6;color:#393744;font-style:italic}.divider{margin:.5rem 40px;border-top:1px solid #ffa77e}\n"] }]
|
|
1939
2036
|
}] });
|
|
1940
2037
|
|
|
1941
2038
|
class ChatMessagesListComponent {
|
|
1942
2039
|
constructor() {
|
|
2040
|
+
// Inputs
|
|
1943
2041
|
this.chatUserSettings = input.required();
|
|
1944
|
-
this.aiIcon = 'assets/default/ai.png';
|
|
1945
|
-
this.conversationService = inject(ConversationService);
|
|
1946
2042
|
this.inputMessages = input.required();
|
|
1947
|
-
//
|
|
1948
|
-
this.
|
|
1949
|
-
|
|
2043
|
+
// Private services
|
|
2044
|
+
this.conversationService = inject(ConversationService);
|
|
2045
|
+
this.elementRef = inject(ElementRef);
|
|
2046
|
+
// State
|
|
2047
|
+
this.aiIcon = 'assets/default/ai.png';
|
|
2048
|
+
this.isThinking = this.conversationService.isThinking();
|
|
1950
2049
|
this.messages = computed(() => {
|
|
1951
2050
|
// Get the actual array of messages from the signal by calling it as a function
|
|
1952
2051
|
const allMessages = this.conversationService.getMessagesSignal()();
|
|
1953
2052
|
console.log('Getting messages', allMessages);
|
|
1954
2053
|
return allMessages.filter((message) => message.role !== ChatRole.System);
|
|
1955
2054
|
});
|
|
1956
|
-
this.isThinking = this.conversationService.isThinking();
|
|
1957
|
-
// Use effect to automatically scroll to bottom when messages change
|
|
1958
2055
|
effect(() => {
|
|
1959
2056
|
// Access the messages to create a dependency
|
|
1960
|
-
const messages = this.messages();
|
|
2057
|
+
const messages = this.messages(); // just to subscribe
|
|
1961
2058
|
// Schedule the scroll after the view has been updated
|
|
1962
2059
|
setTimeout(() => this.scrollToBottom(), 0);
|
|
1963
2060
|
});
|
|
1964
2061
|
}
|
|
2062
|
+
// Note probably i don't need this.
|
|
1965
2063
|
ngAfterViewInit() {
|
|
1966
2064
|
// Initial scroll to bottom when view is initialized
|
|
1967
2065
|
this.scrollToBottom();
|
|
@@ -1971,7 +2069,7 @@ class ChatMessagesListComponent {
|
|
|
1971
2069
|
const element = this.elementRef.nativeElement;
|
|
1972
2070
|
element.scrollTo({
|
|
1973
2071
|
top: element.scrollHeight,
|
|
1974
|
-
behavior: 'smooth'
|
|
2072
|
+
behavior: 'smooth',
|
|
1975
2073
|
});
|
|
1976
2074
|
}
|
|
1977
2075
|
// Track messages by their content and role for efficient rendering
|
|
@@ -1979,11 +2077,11 @@ class ChatMessagesListComponent {
|
|
|
1979
2077
|
return `${message.role}-${index}-${message.content.substring(0, 20)}`;
|
|
1980
2078
|
}
|
|
1981
2079
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessagesListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1982
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessagesListComponent, isStandalone: true, selector: "dc-chat-messages-list", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: true, isRequired: true, transformFunction: null }, inputMessages: { classPropertyName: "inputMessages", publicName: "inputMessages", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"messages-container\">\n @for (message of messages(); track
|
|
2080
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessagesListComponent, isStandalone: true, selector: "dc-chat-messages-list", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: true, isRequired: true, transformFunction: null }, inputMessages: { classPropertyName: "inputMessages", publicName: "inputMessages", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"messages-container\">\n @for (message of messages(); track message.messageId) {\n <dc-chat-message [chatMessage]=\"message\" [chatUserSettings]=\"chatUserSettings()\"> </dc-chat-message>\n } @if (isThinking()) {\n <div class=\"thinking-container\">\n <div class=\"thinking-message\">\n <div class=\"thinking-avatar\">\n <img [src]=\"aiIcon\" alt=\"AI thinking\" class=\"avatar-img\" />\n </div>\n <div class=\"thinking-content\">\n <p-skeleton width=\"80%\" height=\"2rem\"></p-skeleton>\n <p-skeleton width=\"60%\" height=\"2rem\"></p-skeleton>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".messages-container{display:flex;flex-direction:column;gap:1rem;padding:1rem;height:100%}.thinking-container{padding:.5rem 0}.thinking-message{display:flex;gap:1rem;align-items:flex-start}.thinking-avatar{width:40px;height:40px;border-radius:50%;overflow:hidden;flex-shrink:0}.avatar-img{width:100%;height:100%;object-fit:cover}.thinking-content{flex:1;display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "component", type: ChatMessageComponent, selector: "dc-chat-message", inputs: ["chatMessage", "chatUserSettings"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1983
2081
|
}
|
|
1984
2082
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessagesListComponent, decorators: [{
|
|
1985
2083
|
type: Component,
|
|
1986
|
-
args: [{ selector: 'dc-chat-messages-list', standalone: true, imports: [ChatMessageComponent, SkeletonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"messages-container\">\n @for (message of messages(); track
|
|
2084
|
+
args: [{ selector: 'dc-chat-messages-list', standalone: true, imports: [ChatMessageComponent, SkeletonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"messages-container\">\n @for (message of messages(); track message.messageId) {\n <dc-chat-message [chatMessage]=\"message\" [chatUserSettings]=\"chatUserSettings()\"> </dc-chat-message>\n } @if (isThinking()) {\n <div class=\"thinking-container\">\n <div class=\"thinking-message\">\n <div class=\"thinking-avatar\">\n <img [src]=\"aiIcon\" alt=\"AI thinking\" class=\"avatar-img\" />\n </div>\n <div class=\"thinking-content\">\n <p-skeleton width=\"80%\" height=\"2rem\"></p-skeleton>\n <p-skeleton width=\"60%\" height=\"2rem\"></p-skeleton>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: [".messages-container{display:flex;flex-direction:column;gap:1rem;padding:1rem;height:100%}.thinking-container{padding:.5rem 0}.thinking-message{display:flex;gap:1rem;align-items:flex-start}.thinking-avatar{width:40px;height:40px;border-radius:50%;overflow:hidden;flex-shrink:0}.avatar-img{width:100%;height:100%;object-fit:cover}.thinking-content{flex:1;display:flex;flex-direction:column;gap:.5rem}\n"] }]
|
|
1987
2085
|
}], ctorParameters: () => [] });
|
|
1988
2086
|
|
|
1989
2087
|
const SpeedDescription = {
|
|
@@ -2171,28 +2269,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
2171
2269
|
|
|
2172
2270
|
class DCChatComponent {
|
|
2173
2271
|
constructor() {
|
|
2174
|
-
|
|
2272
|
+
// Services
|
|
2175
2273
|
this.dialogService = inject(DialogService);
|
|
2176
2274
|
this.conversationService = inject(ConversationService);
|
|
2275
|
+
this.evaluationService = inject(EvaluationService);
|
|
2177
2276
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
2277
|
+
// Inputs
|
|
2178
2278
|
this.chatUserSettings = this.userDataExchange.getUserChatSettings(); // Default to user data exchange
|
|
2179
|
-
//
|
|
2279
|
+
// Signal Inputs
|
|
2180
2280
|
this.evaluatorAgentCard = input();
|
|
2181
2281
|
this.parseDict = input({});
|
|
2282
|
+
// Outputs
|
|
2182
2283
|
this.sendMessage = output(); // notifies whatever happened inside the chat
|
|
2284
|
+
this.goalCompleted = output(); // notifies when user completes goal (score reaches 100)
|
|
2285
|
+
// Signals States
|
|
2286
|
+
this.messages = signal([]);
|
|
2287
|
+
// States
|
|
2183
2288
|
this.micSettings = { useWhisper: true, lang: 'en' };
|
|
2184
2289
|
this.isInfoVisible = false;
|
|
2185
2290
|
this.isAdmin = true;
|
|
2186
|
-
//
|
|
2187
|
-
|
|
2188
|
-
|
|
2291
|
+
// Subscribe to score updates using effect
|
|
2292
|
+
effect(() => {
|
|
2293
|
+
const score = this.evaluationService.getScore()();
|
|
2294
|
+
if (score >= 100) {
|
|
2295
|
+
this.goalCompleted.emit();
|
|
2296
|
+
}
|
|
2297
|
+
});
|
|
2189
2298
|
}
|
|
2190
2299
|
async ngOnInit() {
|
|
2300
|
+
console.log(this.parseDict());
|
|
2191
2301
|
if (this.conversationSettings) {
|
|
2192
2302
|
await this.conversationService.initConversationWithSettings(this.conversationSettings);
|
|
2193
2303
|
}
|
|
2194
2304
|
else {
|
|
2195
|
-
await this.conversationService.initConversationWithAgentCard(this.agentCard);
|
|
2305
|
+
await this.conversationService.initConversationWithAgentCard(this.agentCard, this.parseDict());
|
|
2196
2306
|
}
|
|
2197
2307
|
}
|
|
2198
2308
|
ngOnDestroy() {
|
|
@@ -2231,12 +2341,12 @@ class DCChatComponent {
|
|
|
2231
2341
|
await this.ngOnInit();
|
|
2232
2342
|
}
|
|
2233
2343
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2234
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, evaluatorAgentCard: { classPropertyName: "evaluatorAgentCard", publicName: "evaluatorAgentCard", isSignal: true, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage" }, providers: [DialogService], ngImport: i0, template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [evaluatorAgentCard]=\"evaluatorAgentCard()\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["isAdmin", "alternativeConversation", "agentCard"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "evaluatorAgentCard", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings", "inputMessages"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2344
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, evaluatorAgentCard: { classPropertyName: "evaluatorAgentCard", publicName: "evaluatorAgentCard", isSignal: true, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", goalCompleted: "goalCompleted" }, providers: [DialogService], ngImport: i0, template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [evaluatorAgentCard]=\"evaluatorAgentCard()\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["isAdmin", "alternativeConversation", "agentCard"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "evaluatorAgentCard", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings", "inputMessages"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2235
2345
|
}
|
|
2236
2346
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCChatComponent, decorators: [{
|
|
2237
2347
|
type: Component,
|
|
2238
2348
|
args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent, DialogModule, ProgressBarModule, SafeJsonPipe], changeDetection: ChangeDetectionStrategy.OnPush, providers: [DialogService], template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [evaluatorAgentCard]=\"evaluatorAgentCard()\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"] }]
|
|
2239
|
-
}], propDecorators: { chatUserSettings: [{
|
|
2349
|
+
}], ctorParameters: () => [], propDecorators: { chatUserSettings: [{
|
|
2240
2350
|
type: Input
|
|
2241
2351
|
}], conversationSettings: [{
|
|
2242
2352
|
type: Input
|
|
@@ -3209,7 +3319,7 @@ class AgentCardListComponent extends PaginationBase {
|
|
|
3209
3319
|
}
|
|
3210
3320
|
}
|
|
3211
3321
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3212
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentCardListComponent, isStandalone: true, selector: "dc-agent-card-lists", inputs: { viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: false, isRequired: false, transformFunction: null }, customCardComponent: { classPropertyName: "customCardComponent", publicName: "customCardComponent", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, gridLayout: { classPropertyName: "gridLayout", publicName: "gridLayout", isSignal: true, isRequired: false, transformFunction: null }, getCustomButtons: { classPropertyName: "getCustomButtons", publicName: "getCustomButtons", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "outlets", predicate: ["outlet"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<dc-filter-bar [isAdmin]=\"true\" (onFilterAction)=\"doFilterBarAction($event)\"></dc-filter-bar>\n\n@if(viewMode === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"agentCards\" [actions]=\"actions()\" (onAction)=\"onCardAction($event)\"></app-quick-table>\n\n}@else{\n\n<div class=\"conversation-card-lists\">\n @if(!isLoading) {\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @for (card of agentCards; track card) {\n <div style=\"position: relative\">\n <ng-container #outlet=\"ngComponentOutlet\" [ngComponentOutlet]=\"cardComponent\" [ngComponentOutletInputs]=\"{ card: card, showOptions: showOptions() }\">\n </ng-container>\n </div>\n }\n </div>\n }\n</div>\n\n@if(isLoading) {\n<div>\n <p-skeleton styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"5rem\" styleClass=\"mb-2\" />\n <p-skeleton height=\"2rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" height=\"4rem\" />\n</div>\n} @if(agentCards.length === 0) {\n<div>\n <p>No conversations found or no connection with server</p>\n</div>\n} }\n\n<p-paginator\n currentPageReportTemplate=\"{{ totalRecords }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [totalRecords]=\"totalRecords\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n</p-paginator>\n", styles: [":host{display:block;height:100%}.options-icon{cursor:pointer;position:absolute;top:2px;right:3px;font-size:1.2rem;color:#dde9e9;background-color:#4f486281;border-radius:50%;padding:5px;z-index:1000}.conversation-card-lists{padding:1.5rem;width:100%;height:100%;display:flex;flex-direction:column}.conversation-card-lists .cards-container{display:flex;flex-wrap:wrap;gap:2rem;width:100%;justify-content:center;flex:1;overflow-y:auto;min-height:0}.conversation-card-lists .cards-container>div{flex:0 0 240px}.conversation-card-lists .dc-card{position:relative;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;padding:.5rem;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column;gap:2px}.conversation-card-lists .dc-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.conversation-card-lists .dc-card .dc-card-header{position:absolute;top:10px;left:5px;border-radius:5px;padding:5px}.conversation-card-lists .dc-card .dc-card-header:before{content:\"\";position:absolute;inset:0;background-color:#4d30db81;filter:blur(2px);border-radius:5px;z-index:0}.conversation-card-lists .dc-card .dc-card-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#ece7e7;position:relative;z-index:1}.conversation-card-lists .dc-card .dc-card-content{flex:1}.conversation-card-lists .dc-card .dc-card-content p{margin:0;color:#666;line-height:1.5}.conversation-card-lists .dc-card button{padding:.5rem 1rem;border:none;border-radius:4px;background-color:#007bff;color:#fff;cursor:pointer;font-weight:500;transition:background-color .2s ease}.conversation-card-lists .dc-card button:hover{background-color:#0056b3}.conversation-card-lists .dc-card button:active{transform:translateY(1px)}:host{display:flex;flex-direction:column;height:100%}p-paginator{margin-top:1rem;flex-shrink:0}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$4.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["isAdmin", "
|
|
3322
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentCardListComponent, isStandalone: true, selector: "dc-agent-card-lists", inputs: { viewMode: { classPropertyName: "viewMode", publicName: "viewMode", isSignal: false, isRequired: false, transformFunction: null }, customCardComponent: { classPropertyName: "customCardComponent", publicName: "customCardComponent", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, gridLayout: { classPropertyName: "gridLayout", publicName: "gridLayout", isSignal: true, isRequired: false, transformFunction: null }, getCustomButtons: { classPropertyName: "getCustomButtons", publicName: "getCustomButtons", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "outlets", predicate: ["outlet"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<dc-filter-bar [isAdmin]=\"true\" (onFilterAction)=\"doFilterBarAction($event)\"></dc-filter-bar>\n\n@if(viewMode === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"agentCards\" [actions]=\"actions()\" (onAction)=\"onCardAction($event)\"></app-quick-table>\n\n}@else{\n\n<div class=\"conversation-card-lists\">\n @if(!isLoading) {\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @for (card of agentCards; track card) {\n <div style=\"position: relative\">\n <ng-container #outlet=\"ngComponentOutlet\" [ngComponentOutlet]=\"cardComponent\" [ngComponentOutletInputs]=\"{ card: card, showOptions: showOptions() }\">\n </ng-container>\n </div>\n }\n </div>\n }\n</div>\n\n@if(isLoading) {\n<div>\n <p-skeleton styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"5rem\" styleClass=\"mb-2\" />\n <p-skeleton height=\"2rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" height=\"4rem\" />\n</div>\n} @if(agentCards.length === 0) {\n<div>\n <p>No conversations found or no connection with server</p>\n</div>\n} }\n\n<p-paginator\n currentPageReportTemplate=\"{{ totalRecords }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"paginatorFirst\"\n [rows]=\"paginatorRows\"\n [totalRecords]=\"totalRecords\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n</p-paginator>\n", styles: [":host{display:block;height:100%}.options-icon{cursor:pointer;position:absolute;top:2px;right:3px;font-size:1.2rem;color:#dde9e9;background-color:#4f486281;border-radius:50%;padding:5px;z-index:1000}.conversation-card-lists{padding:1.5rem;width:100%;height:100%;display:flex;flex-direction:column}.conversation-card-lists .cards-container{display:flex;flex-wrap:wrap;gap:2rem;width:100%;justify-content:center;flex:1;overflow-y:auto;min-height:0}.conversation-card-lists .cards-container>div{flex:0 0 240px}.conversation-card-lists .dc-card{position:relative;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;padding:.5rem;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column;gap:2px}.conversation-card-lists .dc-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.conversation-card-lists .dc-card .dc-card-header{position:absolute;top:10px;left:5px;border-radius:5px;padding:5px}.conversation-card-lists .dc-card .dc-card-header:before{content:\"\";position:absolute;inset:0;background-color:#4d30db81;filter:blur(2px);border-radius:5px;z-index:0}.conversation-card-lists .dc-card .dc-card-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#ece7e7;position:relative;z-index:1}.conversation-card-lists .dc-card .dc-card-content{flex:1}.conversation-card-lists .dc-card .dc-card-content p{margin:0;color:#666;line-height:1.5}.conversation-card-lists .dc-card button{padding:.5rem 1rem;border:none;border-radius:4px;background-color:#007bff;color:#fff;cursor:pointer;font-weight:500;transition:background-color .2s ease}.conversation-card-lists .dc-card button:hover{background-color:#0056b3}.conversation-card-lists .dc-card button:active{transform:translateY(1px)}:host{display:flex;flex-direction:column;height:100%}p-paginator{margin-top:1rem;flex-shrink:0}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$4.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["isAdmin", "items", "customFilters"], outputs: ["onFilterAction", "onChangeSort", "onNew"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
3213
3323
|
}
|
|
3214
3324
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentCardListComponent, decorators: [{
|
|
3215
3325
|
type: Component,
|
|
@@ -3261,7 +3371,6 @@ class DcAgentCardDetailsComponent {
|
|
|
3261
3371
|
this.agentCardService = inject(CONVERSATION_AI_TOKEN);
|
|
3262
3372
|
this.route = inject(ActivatedRoute);
|
|
3263
3373
|
this.cdr = inject(ChangeDetectorRef);
|
|
3264
|
-
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
3265
3374
|
this.agentCardId = '';
|
|
3266
3375
|
this.onStartConversation = output();
|
|
3267
3376
|
this.showInfoLayer = false;
|
|
@@ -3290,12 +3399,12 @@ class DcAgentCardDetailsComponent {
|
|
|
3290
3399
|
this.cdr.markForCheck();
|
|
3291
3400
|
}
|
|
3292
3401
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcAgentCardDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3293
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcAgentCardDetailsComponent, isStandalone: true, selector: "dc-agent-card-details", inputs: { agentCardId: "agentCardId" }, outputs: { onStartConversation: "onStartConversation" }, ngImport: i0, template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard?.assets?.image?.url || 'assets/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div class=\"info-button\" (click)=\"toggleInfoLayer()\">\n <p-button icon=\"pi pi-arrow-down-left\" [rounded]=\"true\" [raised]=\"true\" severity=\"primary\" [outlined]=\"true\" />\n </div>\n\n <div style=\"position: absolute; bottom: 20px; right: 50%; transform: translateX(50%); z-index: 3\">\n <p-button size=\"large\" label=\"Iniciar Conversaci\u00F3n\" [rounded]=\"true\" (click)=\"startConversation()\" />\n </div>\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard?.title }}</strong></h1\n
|
|
3402
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcAgentCardDetailsComponent, isStandalone: true, selector: "dc-agent-card-details", inputs: { agentCardId: "agentCardId" }, outputs: { onStartConversation: "onStartConversation" }, ngImport: i0, template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard?.assets?.image?.url || 'assets/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div class=\"info-button\" (click)=\"toggleInfoLayer()\">\n <p-button icon=\"pi pi-arrow-down-left\" [rounded]=\"true\" [raised]=\"true\" severity=\"primary\" [outlined]=\"true\" />\n </div>\n\n <div style=\"position: absolute; bottom: 20px; right: 50%; transform: translateX(50%); z-index: 3\">\n <p-button size=\"large\" label=\"Iniciar Conversaci\u00F3n\" [rounded]=\"true\" (click)=\"startConversation()\" />\n </div>\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard?.title }}</strong></h1\n >\n <p>{{ agentCard?.characterCard.data?.name }}</p>\n\n @if (agentCard?.characterCard.data?.scenario) {\n <div class=\"scenario\">\n <h4>Scenario</h4>\n <p>{{ agentCard?.characterCard.data.scenario | parseCard : agentCard }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n </p-card>\n</div>\n", styles: ["::ng-deep .p-card{width:420px;height:700px}::ng-deep .p-card .p-card-body{width:100%;height:100%}.card-image{height:100%;width:100%;object-fit:cover;object-position:center;position:absolute;top:0;left:0;transition:filter .3s ease}.info-button{position:absolute;top:15px;right:15px;z-index:3}.info-button:hover{transform:scale(1.1)}.info-layer{height:100%;width:100%;position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;z-index:2;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:#ed122833;color:#fff;opacity:1;clip-path:circle(0% at top right);transition:clip-path .5s cubic-bezier(.25,1,.5,1);pointer-events:none}.info-layer.active{clip-path:circle(150% at top right);pointer-events:auto}.info-content{padding:15px;text-align:center;max-width:90%}.info-content h1{margin-top:0;font-size:18px;margin-bottom:10px}.info-content p{font-size:12px;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "pipe", type: ParseCardPipe, name: "parseCard" }] }); }
|
|
3294
3403
|
}
|
|
3295
3404
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcAgentCardDetailsComponent, decorators: [{
|
|
3296
3405
|
type: Component,
|
|
3297
|
-
args: [{ selector: 'dc-agent-card-details', standalone: true, imports: [ButtonModule, CardModule, ParseCardPipe], template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard?.assets?.image?.url || 'assets/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div class=\"info-button\" (click)=\"toggleInfoLayer()\">\n <p-button icon=\"pi pi-arrow-down-left\" [rounded]=\"true\" [raised]=\"true\" severity=\"primary\" [outlined]=\"true\" />\n </div>\n\n <div style=\"position: absolute; bottom: 20px; right: 50%; transform: translateX(50%); z-index: 3\">\n <p-button size=\"large\" label=\"Iniciar Conversaci\u00F3n\" [rounded]=\"true\" (click)=\"startConversation()\" />\n </div>\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard?.title }}</strong></h1\n
|
|
3298
|
-
}],
|
|
3406
|
+
args: [{ selector: 'dc-agent-card-details', standalone: true, imports: [ButtonModule, CardModule, ParseCardPipe], template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard?.assets?.image?.url || 'assets/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div class=\"info-button\" (click)=\"toggleInfoLayer()\">\n <p-button icon=\"pi pi-arrow-down-left\" [rounded]=\"true\" [raised]=\"true\" severity=\"primary\" [outlined]=\"true\" />\n </div>\n\n <div style=\"position: absolute; bottom: 20px; right: 50%; transform: translateX(50%); z-index: 3\">\n <p-button size=\"large\" label=\"Iniciar Conversaci\u00F3n\" [rounded]=\"true\" (click)=\"startConversation()\" />\n </div>\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard?.title }}</strong></h1\n >\n <p>{{ agentCard?.characterCard.data?.name }}</p>\n\n @if (agentCard?.characterCard.data?.scenario) {\n <div class=\"scenario\">\n <h4>Scenario</h4>\n <p>{{ agentCard?.characterCard.data.scenario | parseCard : agentCard }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n </p-card>\n</div>\n", styles: ["::ng-deep .p-card{width:420px;height:700px}::ng-deep .p-card .p-card-body{width:100%;height:100%}.card-image{height:100%;width:100%;object-fit:cover;object-position:center;position:absolute;top:0;left:0;transition:filter .3s ease}.info-button{position:absolute;top:15px;right:15px;z-index:3}.info-button:hover{transform:scale(1.1)}.info-layer{height:100%;width:100%;position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;z-index:2;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:#ed122833;color:#fff;opacity:1;clip-path:circle(0% at top right);transition:clip-path .5s cubic-bezier(.25,1,.5,1);pointer-events:none}.info-layer.active{clip-path:circle(150% at top right);pointer-events:auto}.info-content{padding:15px;text-align:center;max-width:90%}.info-content h1{margin-top:0;font-size:18px;margin-bottom:10px}.info-content p{font-size:12px;margin:0}\n"] }]
|
|
3407
|
+
}], propDecorators: { agentCardId: [{
|
|
3299
3408
|
type: Input
|
|
3300
3409
|
}] } });
|
|
3301
3410
|
|
|
@@ -3308,7 +3417,7 @@ const DefaultEvaluatorAgentCard = {
|
|
|
3308
3417
|
task: 'Evaluate the user understanding of the lesson',
|
|
3309
3418
|
messages: [],
|
|
3310
3419
|
expectedResponseType: EvalResultStringDefinition,
|
|
3311
|
-
model: { id: '
|
|
3420
|
+
model: { id: '', provider: 'google' },
|
|
3312
3421
|
sources: [],
|
|
3313
3422
|
};
|
|
3314
3423
|
|