Skip to content

Commit

Permalink
[Tock Studio] Filter dialogs with rag responses + Create new Faq from…
Browse files Browse the repository at this point in the history
… rag response (#1657)

* dercbot-1065-1073-Filter rag dialogs and create faq from rag answer

* Use of condensed question if debug enabled
  • Loading branch information
rkuffer authored Jun 28, 2024
1 parent 6f2f3fb commit 276a132
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 111 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<nb-card class="mb-2">
<nb-card-body class="d-flex flew-wrap gap-1 align-items-center">
<nb-card-body class="d-flex flex-wrap gap-1 align-items-center">
<ng-container *ngIf="!ratingFilter">
<div class="flex-grow-1 min-width-10 d-flex gap-1 align-items-center">
<div class="flex-grow-1 min-width-15 w-100 d-flex gap-1 align-items-center">
<input
nbInput
fullWidth
Expand All @@ -17,75 +17,93 @@
</nb-checkbox>
</div>

<nb-select
fullWidth
placeholder="Connector type"
[(ngModel)]="filter.connectorType"
(selectedChange)="refresh()"
>
<nb-option
*ngFor="let c of connectorTypes"
[value]="c"
>{{ c.id }}</nb-option
<div class="d-flex gap-1">
<nb-select
fullWidth
placeholder="Connector type"
class="min-width-15"
[(ngModel)]="filter.connectorType"
(selectedChange)="refresh()"
>
</nb-select>
<nb-option
*ngFor="let c of connectorTypes"
[value]="c"
>{{ c.id }}</nb-option
>
</nb-select>

<nb-select
fullWidth
placeholder="Intent"
[(ngModel)]="filter.intentName"
(selectedChange)="refresh()"
>
<nb-option value="">All</nb-option>
<nb-option
*ngFor="let intent of state.currentApplication.intents"
[value]="intent.name"
<nb-select
fullWidth
placeholder="Intent"
class="min-width-15"
[(ngModel)]="filter.intentName"
(selectedChange)="refresh()"
>
{{ intent.name }}
</nb-option>
<nb-option value="unknown">Unknown</nb-option>
</nb-select>
<nb-option value="">All</nb-option>
<nb-option
*ngFor="let intent of state.currentApplication.intents"
[value]="intent.name"
>
{{ intent.name }}
</nb-option>
<nb-option value="unknown">Unknown</nb-option>
</nb-select>
</div>
</ng-container>

<ng-container *ngIf="ratingFilter">
<nb-select
fullWidth
placeholder="Configuration"
[(ngModel)]="filter.configuration"
(selectedChange)="refresh()"
>
<nb-option value="">All</nb-option>
<nb-option
*ngFor="let config of configurationNameList"
[value]="config"
<div class="d-flex gap-1">
<nb-select
fullWidth
placeholder="Configuration"
[(ngModel)]="filter.configuration"
(selectedChange)="refresh()"
class="min-width-15"
>
{{ config }}
</nb-option>
</nb-select>
<nb-option value="">All</nb-option>
<nb-option
*ngFor="let config of configurationNameList"
[value]="config"
>
{{ config }}
</nb-option>
</nb-select>

<nb-select
fullWidth
multiple
placeholder="Intents"
[(ngModel)]="filter.intentsToHide"
(selectedChange)="refresh()"
>
<nb-option>Clear selection</nb-option>
<nb-option
*ngFor="let intent of intents"
[value]="intent"
<nb-select
fullWidth
multiple
placeholder="Intents"
[(ngModel)]="filter.intentsToHide"
(selectedChange)="refresh()"
class="min-width-15"
>
{{ intent }}
</nb-option>
</nb-select>
<nb-option>Clear selection</nb-option>
<nb-option
*ngFor="let intent of intents"
[value]="intent"
>
{{ intent }}
</nb-option>
</nb-select>
</div>
</ng-container>

<nb-toggle
class="nb-toggle-reset-label-margin text-nowrap"
<nb-checkbox
*ngIf="!ratingFilter"
nbTooltip="Display only dialogs containing Rag responses"
class="text-nowrap"
[(ngModel)]="filter.isGenAiRagDialog"
(change)="waitAndRefresh()"
>Rag responses only
</nb-checkbox>

<nb-checkbox
nbTooltip="Display dialogues held from the studio test view"
class="text-nowrap"
[(ngModel)]="filter.displayTests"
(change)="waitAndRefresh()"
>Display tests</nb-toggle
>
>Display tests
</nb-checkbox>
</nb-card-body>
</nb-card>

Expand All @@ -111,16 +129,32 @@ <h1 *ngIf="total === 0">
<nb-card>
<nb-card-body class="p-1 pt-2">
<tock-chat-ui>
<tock-chat-ui-message
*ngFor="let action of dialog.actions"
[message]="action.message"
[date]="action.date"
[reply]="action.isBot()"
[replay]="true"
[sender]="getUserName(action)"
[avatar]="getUserAvatar(action)"
>
</tock-chat-ui-message>
<ng-container *ngFor="let action of dialog.actions">
<tock-chat-ui-message
[message]="action.message"
[date]="action.date"
[reply]="action.isBot()"
[replay]="true"
[sender]="getUserName(action)"
[avatar]="getUserAvatar(action)"
>
<div
*ngIf="action.metadata.isGenAiRagAnswer"
class="mt-3 text-right"
>
<button
nbButton
size="tiny"
status="warning"
type="button"
(click)="createFaq(action, dialog.actions)"
>
<nb-icon icon="message-square-outline"></nb-icon>
Create a FAQ with this question/answer pair
</button>
</div>
</tock-chat-ui-message>
</ng-container>
</tock-chat-ui>
</nb-card-body>
</nb-card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,3 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

.min-width-10 {
min-width: 25rem;
}
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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
) {}
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions bot/admin/web/src/app/analytics/dialogs/dialogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions bot/admin/web/src/app/analytics/users/users.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -175,7 +179,3 @@ export class UsersComponent extends ScrollComponent<UserReport> {
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 = '') {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@
First question (out of {{ faq.utterances.length }})
</small>
{{ faq.utterances[0] }}
<button
nbButton
ghost
size="tiny"
nbTooltip="Copy question"
(click)="copyString(faq.utterances[0])"
>
<nb-icon icon="copy-outline"></nb-icon>
</button>
</div>
</div>

Expand Down
Loading

0 comments on commit 276a132

Please sign in to comment.