From 276a13251f865c82d37ebf39af5b4f657c563b01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rodolphe=20K=C3=BCffer?=
<101799433+rkuffer@users.noreply.github.com>
Date: Fri, 28 Jun 2024 14:51:19 +0200
Subject: [PATCH] [Tock Studio] Filter dialogs with rag responses + Create new
Faq from rag response (#1657)
* dercbot-1065-1073-Filter rag dialogs and create faq from rag answer
* Use of condensed question if debug enabled
---
.../dialogs-list/dialogs-list.component.html | 170 +++++++++++-------
.../dialogs-list/dialogs-list.component.scss | 4 -
.../dialogs-list/dialogs-list.component.ts | 39 +++-
.../web/src/app/analytics/dialogs/dialogs.ts | 4 +-
.../app/analytics/users/users.component.ts | 8 +-
.../faq-management-edit.component.spec.ts | 2 +-
.../faq-management-edit.component.ts | 13 +-
.../faq-management-list.component.html | 9 +
.../faq-management-list.component.ts | 9 +-
.../faq-management.component.ts | 36 ++--
.../chat-ui-message-debug.component.ts | 6 +-
.../web/src/app/theme/styles/utilities.scss | 16 ++
12 files changed, 205 insertions(+), 111 deletions(-)
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html
index d4d80353aa..1d72817c67 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.html
@@ -1,7 +1,7 @@
-
+
-
+
-
- {{ c.id }}
+
-
+ {{ c.id }}
+
-
- All
-
- {{ intent.name }}
-
- Unknown
-
+
All
+
+ {{ intent.name }}
+
+
Unknown
+
+
-
- All
-
+
- {{ config }}
-
-
+ All
+
+ {{ config }}
+
+
-
- Clear selection
-
- {{ intent }}
-
-
+ Clear selection
+
+ {{ intent }}
+
+
+
- Rag responses only
+
+
+ Display tests
+ >Display tests
+
@@ -111,16 +129,32 @@
-
-
+
+
+
+
+
+
+
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss
index d6b167136c..824227d493 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.scss
@@ -13,7 +13,3 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-.min-width-10 {
- min-width: 25rem;
-}
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts
index 53274a1da0..1827528ec9 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs-list/dialogs-list.component.ts
@@ -1,15 +1,15 @@
import { Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
-import { ActionReport, DialogReport } from '../../../shared/model/dialog-data';
+import { ActionReport, Debug, DialogReport, SentenceWithFootnotes } from '../../../shared/model/dialog-data';
import { ConnectorType } from '../../../core/model/configuration';
import { StateService } from '../../../core-nlp/state.service';
import { DialogReportQuery } from '../dialogs';
import { AnalyticsService } from '../../analytics.service';
import { BotConfigurationService } from '../../../core/bot-configuration.service';
-import { ActivatedRoute, UrlSegment } from '@angular/router';
+import { ActivatedRoute, Router, UrlSegment } from '@angular/router';
import { BotSharedService } from '../../../shared/bot-shared.service';
import { PaginatedQuery, SearchMark } from '../../../model/commons';
import { BehaviorSubject, Observable, Subject, filter, mergeMap, take, takeUntil } from 'rxjs';
-import { PaginatedResult } from '../../../model/nlp';
+import { PaginatedResult, Sentence } from '../../../model/nlp';
import { saveAs } from 'file-saver-es';
import { getDialogMessageUserAvatar, getDialogMessageUserQualifier } from '../../../shared/utils';
@@ -23,8 +23,8 @@ export class DialogFilter {
public connectorType?: ConnectorType,
public ratings?: number[],
public configuration?: string,
-
- public intentsToHide?: string[]
+ public intentsToHide?: string[],
+ public isGenAiRagDialog?: boolean
) {}
}
@@ -67,7 +67,8 @@ export class DialogsListComponent implements OnInit, OnChanges, OnDestroy {
private analytics: AnalyticsService,
private botConfiguration: BotConfigurationService,
private route: ActivatedRoute,
- public botSharedService: BotSharedService
+ public botSharedService: BotSharedService,
+ private router: Router
) {
this.state = state;
@@ -143,7 +144,8 @@ export class DialogsListComponent implements OnInit, OnChanges, OnDestroy {
this.filter.displayTests,
this.ratingFilter,
this.filter.configuration,
- this.filter.intentsToHide
+ this.filter.intentsToHide,
+ this.filter.isGenAiRagDialog
);
return this.route.queryParams.pipe(
@@ -219,6 +221,29 @@ export class DialogsListComponent implements OnInit, OnChanges, OnDestroy {
return getDialogMessageUserAvatar(action.isBot());
}
+ createFaq(action: ActionReport, actionsStack: ActionReport[]) {
+ const actionIndex = actionsStack.findIndex((act) => act === action);
+ if (actionIndex > 0) {
+ const answerSentence = action.message as unknown as SentenceWithFootnotes;
+ const answer = answerSentence.text;
+
+ let question;
+ const questionAction = actionsStack[actionIndex - 1];
+
+ if (questionAction.message.isDebug()) {
+ const actionDebug = questionAction.message as unknown as Debug;
+ question = actionDebug.data.condense_question || actionDebug.data.user_question;
+ } else if (!questionAction.isBot()) {
+ const questionSentence = questionAction.message as unknown as Sentence;
+ question = questionSentence.text;
+ }
+
+ if (question && answer) {
+ this.router.navigate(['faq/management'], { state: { question, answer } });
+ }
+ }
+ }
+
ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.complete();
diff --git a/bot/admin/web/src/app/analytics/dialogs/dialogs.ts b/bot/admin/web/src/app/analytics/dialogs/dialogs.ts
index f9c649c0a2..2c0bb1f000 100644
--- a/bot/admin/web/src/app/analytics/dialogs/dialogs.ts
+++ b/bot/admin/web/src/app/analytics/dialogs/dialogs.ts
@@ -34,8 +34,8 @@ export class DialogReportQuery extends PaginatedQuery {
public displayTests?: boolean,
public ratings?: number[],
public applicationId?: string,
-
- public intentsToHide? : string[]
+ public intentsToHide?: string[],
+ public isGenAiRagDialog?: boolean
) {
super(namespace, applicationName, language, start, size);
}
diff --git a/bot/admin/web/src/app/analytics/users/users.component.ts b/bot/admin/web/src/app/analytics/users/users.component.ts
index faac07cd4d..1d80ae8bc3 100644
--- a/bot/admin/web/src/app/analytics/users/users.component.ts
+++ b/bot/admin/web/src/app/analytics/users/users.component.ts
@@ -30,6 +30,10 @@ import { BotApplicationConfiguration, ConnectorType } from '../../core/model/con
import { TestPlan } from '../../test/model/test';
import { getDialogMessageUserAvatar, getDialogMessageUserQualifier } from '../../shared/utils';
+export class UserFilter {
+ constructor(public flags: string[], public displayTests: boolean, public from?: Date, public to?: Date, public intent: string = '') {}
+}
+
@Component({
selector: 'tock-users',
templateUrl: './users.component.html',
@@ -175,7 +179,3 @@ export class UsersComponent extends ScrollComponent {
return user.userPreferences.picture ? user.userPreferences.picture : getDialogMessageUserAvatar(false);
}
}
-
-export class UserFilter {
- constructor(public flags: string[], public displayTests: boolean, public from?: Date, public to?: Date, public intent: string = '') {}
-}
diff --git a/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.spec.ts b/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.spec.ts
index 60187e18ce..b3a68d28d3 100644
--- a/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.spec.ts
+++ b/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.spec.ts
@@ -230,7 +230,7 @@ describe('FaqManagementEditComponent', () => {
enabled: true,
applicationName: 'app',
language: 'fr',
- _initUtterance: 'test'
+ _initQuestion: 'test'
};
component.ngOnChanges({ faq: new SimpleChange(null, faq, true) });
fixture.detectChanges();
diff --git a/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.ts b/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.ts
index 98223c530c..cc675f07b0 100644
--- a/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.ts
+++ b/bot/admin/web/src/app/faq/faq-management/faq-management-edit/faq-management-edit.component.ts
@@ -1,10 +1,9 @@
import { Component, ElementRef, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild } from '@angular/core';
import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import { NbDialogService, NbTabComponent, NbTagComponent, NbTagInputAddEvent } from '@nebular/theme';
-import { Observable, Subscription, of } from 'rxjs';
+import { Observable, of } from 'rxjs';
import { take } from 'rxjs/operators';
-import { DialogService } from '../../../core-nlp/dialog.service';
import { StateService } from '../../../core-nlp/state.service';
import { PaginatedQuery } from '../../../model/commons';
import { Intent, SearchQuery, SentenceStatus } from '../../../model/nlp';
@@ -120,20 +119,20 @@ export class FaqManagementEditComponent implements OnChanges {
this.utterances.push(new FormControl(utterance));
});
- if (faq._initUtterance) {
+ if (faq._initQuestion) {
this.form.markAsDirty();
this.form.markAsTouched();
this.setCurrentTab({ tabTitle: FaqTabs.QUESTION } as NbTabComponent);
setTimeout(() => {
- this.addUtterance(faq._initUtterance);
- delete faq._initUtterance;
+ this.addUtterance(faq._initQuestion);
+ delete faq._initQuestion;
});
}
}
- if (!faq.id && !faq._initUtterance) {
+ if (!faq.id && !faq._initQuestion) {
this.setCurrentTab({ tabTitle: FaqTabs.INFO } as NbTabComponent);
}
}
@@ -199,7 +198,7 @@ export class FaqManagementEditComponent implements OnChanges {
this.intentNameExistInApp = undefined;
}
- addUtterance(utt?) {
+ addUtterance(utt?: string) {
this.resetAlerts();
let utterance = utt || this.addUtteranceInput.nativeElement.value.trim();
diff --git a/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.html b/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.html
index 765bee11b9..b043109f0c 100644
--- a/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.html
+++ b/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.html
@@ -34,6 +34,15 @@
First question (out of {{ faq.utterances.length }})
{{ faq.utterances[0] }}
+
diff --git a/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.ts b/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.ts
index 27295c54e6..206c3ffa45 100644
--- a/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.ts
+++ b/bot/admin/web/src/app/faq/faq-management/faq-management-list/faq-management-list.component.ts
@@ -5,6 +5,8 @@ import { FaqDefinitionExtended } from '../faq-management.component';
import { StateService } from '../../../core-nlp/state.service';
import { DialogService } from '../../../core-nlp/dialog.service';
import { ConfirmDialogComponent } from '../../../shared-nlp/confirm-dialog/confirm-dialog.component';
+import { copyToClipboard } from '../../../shared/utils';
+import { NbToastrService } from '@nebular/theme';
@Component({
selector: 'tock-faq-management-list',
@@ -19,7 +21,7 @@ export class FaqManagementListComponent {
@Output() onDelete = new EventEmitter();
@Output() onEnable = new EventEmitter();
- constructor(private state: StateService, private dialogService: DialogService) {}
+ constructor(private state: StateService, private dialogService: DialogService, private toastrService: NbToastrService) {}
toggleEnabled(faq: FaqDefinitionExtended) {
let action = 'Enable';
@@ -68,4 +70,9 @@ export class FaqManagementListComponent {
saveAs(jsonBlob, `${this.state.currentApplication.name}_${this.state.currentLocale}_faq_${faq.title}.json`);
}
+
+ copyString(str: string) {
+ copyToClipboard(str);
+ this.toastrService.success(`String copied to clipboard`, 'Clipboard');
+ }
}
diff --git a/bot/admin/web/src/app/faq/faq-management/faq-management.component.ts b/bot/admin/web/src/app/faq/faq-management/faq-management.component.ts
index 65df4ad0c4..f394de9b55 100644
--- a/bot/admin/web/src/app/faq/faq-management/faq-management.component.ts
+++ b/bot/admin/web/src/app/faq/faq-management/faq-management.component.ts
@@ -15,7 +15,7 @@ import { FaqManagementEditComponent } from './faq-management-edit/faq-management
import { FaqManagementSettingsComponent } from './faq-management-settings/faq-management-settings.component';
import { Pagination } from '../../shared/components';
-export type FaqDefinitionExtended = FaqDefinition & { _initUtterance?: string };
+export type FaqDefinitionExtended = FaqDefinition & { _initQuestion?: string };
@Component({
selector: 'tock-faq-management',
@@ -44,7 +44,8 @@ export class FaqManagementComponent implements OnInit, OnDestroy {
list: false
};
- initUtterance: string;
+ initQuestion: string;
+ initAnswer: string;
constructor(
private botConfiguration: BotConfigurationService,
@@ -53,7 +54,8 @@ export class FaqManagementComponent implements OnInit, OnDestroy {
private toastrService: NbToastrService,
private router: Router
) {
- this.initUtterance = this.router.getCurrentNavigation().extras?.state?.question;
+ this.initQuestion = this.router.getCurrentNavigation().extras?.state?.question;
+ this.initAnswer = this.router.getCurrentNavigation().extras?.state?.answer;
}
ngOnInit(): void {
@@ -64,10 +66,20 @@ export class FaqManagementComponent implements OnInit, OnDestroy {
this.search();
this.closeSidePanel();
- if (this.initUtterance) {
- let initUtterance = this.initUtterance;
- this.initUtterance = undefined;
- this.addFaq(initUtterance);
+ let initQuestion;
+ if (this.initQuestion) {
+ initQuestion = this.initQuestion;
+ this.initQuestion = undefined;
+ }
+
+ let initAnswer;
+ if (this.initAnswer) {
+ initAnswer = this.initAnswer;
+ this.initAnswer = undefined;
+ }
+
+ if (initQuestion || initAnswer) {
+ this.addFaq(initQuestion, initAnswer);
}
}
});
@@ -201,22 +213,22 @@ export class FaqManagementComponent implements OnInit, OnDestroy {
}
}
- addFaq(initUtterance?: string) {
+ addFaq(initQuestion?: string, initAnswer?: string) {
this.faqEdit = {
id: undefined,
intentId: undefined,
- title: initUtterance ? initUtterance : '',
+ title: initQuestion || '',
description: '',
utterances: [],
tags: [],
- answer: '',
+ answer: initAnswer || '',
enabled: true,
applicationName: this.stateService.currentApplication.name,
language: this.stateService.currentLocale
};
- if (initUtterance) {
- this.faqEdit._initUtterance = initUtterance;
+ if (initQuestion) {
+ this.faqEdit._initQuestion = initQuestion;
}
this.isSidePanelOpen.edit = true;
diff --git a/bot/admin/web/src/app/shared/components/chat-ui/chat-ui-message/chat-ui-message-debug/chat-ui-message-debug.component.ts b/bot/admin/web/src/app/shared/components/chat-ui/chat-ui-message/chat-ui-message-debug/chat-ui-message-debug.component.ts
index efec21e1c1..1e5c81c852 100644
--- a/bot/admin/web/src/app/shared/components/chat-ui/chat-ui-message/chat-ui-message-debug/chat-ui-message-debug.component.ts
+++ b/bot/admin/web/src/app/shared/components/chat-ui/chat-ui-message/chat-ui-message-debug/chat-ui-message-debug.component.ts
@@ -8,14 +8,10 @@ import { DebugViewerDialogComponent } from '../../../debug-viewer-dialog/debug-v
templateUrl: './chat-ui-message-debug.component.html',
styleUrls: ['./chat-ui-message-debug.component.scss']
})
-export class ChatUiMessageDebugComponent implements OnInit {
+export class ChatUiMessageDebugComponent {
@Input() message: Debug;
constructor(private nbDialogService: NbDialogService) {}
- ngOnInit(): void {
- console.log(this.message);
- }
-
showDebug() {
this.nbDialogService.open(DebugViewerDialogComponent, {
context: {
diff --git a/bot/admin/web/src/app/theme/styles/utilities.scss b/bot/admin/web/src/app/theme/styles/utilities.scss
index 28de36f5f7..d321584067 100644
--- a/bot/admin/web/src/app/theme/styles/utilities.scss
+++ b/bot/admin/web/src/app/theme/styles/utilities.scss
@@ -189,3 +189,19 @@ nb-menu {
}
}
}
+
+.min-width-5 {
+ min-width: 5em;
+}
+
+.min-width-10 {
+ min-width: 10em;
+}
+
+.min-width-15 {
+ min-width: 15em;
+}
+
+.min-width-20 {
+ min-width: 20em;
+}