Skip to content

Commit

Permalink
resolves #1418 Import model of shared namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
vsct-jburet committed Jan 5, 2023
1 parent 2a5b4d8 commit fc0e357
Show file tree
Hide file tree
Showing 24 changed files with 164 additions and 51 deletions.
3 changes: 2 additions & 1 deletion bot/admin/web/src/app/configuration/bot/new-bot.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ export class NewBotComponent implements OnInit {
true,
false,
0.0,
false
false,
[]
);
this.applicationService.saveApplication(newApp).subscribe((app) => {
this.applicationService.refreshCurrentApplication(app);
Expand Down
2 changes: 1 addition & 1 deletion nlp/admin/server/src/main/kotlin/AdminService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ object AdminService {

fun getApplicationWithIntents(application: ApplicationDefinition): ApplicationWithIntents {
val intents = front.getIntentsByApplicationId(application._id).sortedBy { it.name }
return ApplicationWithIntents(application, intents)
return ApplicationWithIntents(application, intents, front.getModelSharedIntents(application.namespace))
}

fun createOrGetIntent(namespace: String, intent: IntentDefinition): IntentDefinition? {
Expand Down
6 changes: 5 additions & 1 deletion nlp/admin/server/src/main/kotlin/AdminVerticle.kt
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,11 @@ open class AdminVerticle : WebVerticle() {
|| appWithSameName.normalizeText != newApp.normalizeText) {
front.triggerBuild(ModelBuildTrigger(newApp._id, true))
}
ApplicationWithIntents(newApp, front.getIntentsByApplicationId(newApp._id))
ApplicationWithIntents(
newApp,
front.getIntentsByApplicationId(newApp._id),
front.getModelSharedIntents(application.namespace),
)
} else {
unauthorized()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,17 @@ data class ApplicationWithIntents(
* Normalized text model - sentences are persisted with normalizedText.
*/
val normalizeText: Boolean = false,
/**
* The shared intent definitions for other namespaces.
*/
val namespaceIntents: List<IntentDefinition> = emptyList(),
/**
* The id of the app.
*/
val _id: Id<ApplicationDefinition>?
) {

constructor(application: ApplicationDefinition, intents: List<IntentDefinition>) :
constructor(application: ApplicationDefinition, intents: List<IntentDefinition>, namespacesIntents: List<IntentDefinition>) :
this(
application.name,
application.label,
Expand All @@ -90,6 +94,7 @@ data class ApplicationWithIntents(
application.supportSubEntities,
application.unknownIntentThreshold,
application.normalizeText,
namespacesIntents.sortedWith(compareBy({ it.label }, { it.name })),
application._id
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ export class ApplicationComponent implements OnInit {
true,
false,
0.0,
false
false,
[],
);
}
this.nlpEngineType = this.application.nlpEngineType.name;
Expand Down
19 changes: 19 additions & 0 deletions nlp/admin/web/src/app/core-nlp/state.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export class StateService implements AuthListener {
readonly entities: BehaviorSubject<EntityDefinition[]> = new BehaviorSubject([]);
readonly currentIntents: BehaviorSubject<Intent[]> = new BehaviorSubject([]);
readonly currentIntentsCategories: BehaviorSubject<IntentsCategory[]> = new BehaviorSubject([]);
readonly currentNamespaceIntentsCategories: BehaviorSubject<IntentsCategory[]> = new BehaviorSubject([]);
readonly configurationChange: Subject<boolean> = new Subject();

currentApplication: Application;
Expand Down Expand Up @@ -138,6 +139,16 @@ export class StateService implements AuthListener {
this.currentIntentsCategories.next(
categories.sort((a, b) => a.category.localeCompare(b.category))
);

const namespaceCategories = [];
groupBy(this.currentApplication.intents.concat(this.currentApplication.namespaceIntents), (i) => (i.category ? i.category : 'default')).forEach(
(intents, category) => {
namespaceCategories.push(new IntentsCategory(category, intents));
}
);
this.currentNamespaceIntentsCategories.next(
namespaceCategories.sort((a, b) => a.category.localeCompare(b.category))
);
}

addIntent(intent: Intent) {
Expand All @@ -160,6 +171,14 @@ export class StateService implements AuthListener {
return this.currentApplication.intents.find((i) => i._id === id);
}

findSharedNamespaceIntentById(id: string): Intent {
return this.findIntentById(id) ?? this.currentApplication.namespaceIntents.find((i) => i._id === id);
}

isOtherNamespaceIntent(intent: Intent) : boolean {
return intent && this.currentApplication.isOtherNamespaceIntent(intent);
}

findIntentByName(name: string): Intent {
return this.currentApplication.intents.find((i) => i.name === name);
}
Expand Down
4 changes: 2 additions & 2 deletions nlp/admin/web/src/app/intents/intents.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ button:focus {
}

.entities {
width: 30%;
width: 25%;
text-align: center;
}

Expand All @@ -116,5 +116,5 @@ button:focus {
}

.intent {
width: 15%;
width: 200px
}
19 changes: 10 additions & 9 deletions nlp/admin/web/src/app/intents/intents.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ <h4 class="title">No Intent found</h4>
<span
*ngIf="!row.data.expandable"
class="intent_name"
nbTooltip="{{ row.data.name }}"
>{{ row.data.intentLabel() }}</span
nbTooltip="{{ row.data.qualifiedName() }}"
>{{ state.isOtherNamespaceIntent(row.data) ? row.data.qualifiedName() : row.data.intentLabel() }}</span
>
<div
*ngIf="state.intentExistsInOtherApplication(row.data.name)"
Expand Down Expand Up @@ -116,7 +116,7 @@ <h4 class="title">No Intent found</h4>
>{{ e.qualifiedName(state.user) }}</span
>
<button
*ngIf="!state.intentExistsInOtherApplication(row.data.name)"
*ngIf="!state.intentExistsInOtherApplication(row.data.name) && !state.isOtherNamespaceIntent(row.data)"
nbButton
size="tiny"
ghost
Expand Down Expand Up @@ -147,6 +147,7 @@ <h4 class="title">No Intent found</h4>
>
<div *ngIf="!row.data.expandable">
<button
*ngIf = "!state.isOtherNamespaceIntent(row.data)"
[disabled]="selectedIntent == row.data"
nbButton
size="small"
Expand All @@ -162,7 +163,7 @@ <h4 class="title">No Intent found</h4>
class="shared_list"
>
<mat-chip-list
*ngIf="!state.intentExistsInOtherApplication(row.data.name)"
*ngIf="!state.intentExistsInOtherApplication(row.data.name) && !state.isOtherNamespaceIntent(row.data)"
nbTooltip="Shared intent - click to remove"
>
<mat-chip
Expand All @@ -175,7 +176,7 @@ <h4 class="title">No Intent found</h4>
</mat-chip>
</mat-chip-list>
<mat-chip-list
*ngIf="state.intentExistsInOtherApplication(row.data.name)"
*ngIf="state.intentExistsInOtherApplication(row.data.name) && !state.isOtherNamespaceIntent(row.data)"
nbTooltip="Shared intent"
>
<mat-chip
Expand Down Expand Up @@ -205,7 +206,7 @@ <h4 class="title">No Intent found</h4>
>
<div *ngIf="!row.data.expandable">
<button
*ngIf="!state.intentExistsInOtherApplication(row.data.name)"
*ngIf="!state.intentExistsInOtherApplication(row.data.name) && !state.isOtherNamespaceIntent(row.data)"
nbButton
size="small"
ghost
Expand All @@ -220,7 +221,7 @@ <h4 class="title">No Intent found</h4>
class="shared_list"
>
<mat-chip-list
*ngIf="!state.intentExistsInOtherApplication(row.data.name)"
*ngIf="!state.intentExistsInOtherApplication(row.data.name) && !state.isOtherNamespaceIntent(row.data)"
nbTooltip="Mandatory states - click to delete"
>
<br />
Expand All @@ -234,7 +235,7 @@ <h4 class="title">No Intent found</h4>
</mat-chip>
</mat-chip-list>
<mat-chip-list
*ngIf="state.intentExistsInOtherApplication(row.data.name)"
*ngIf="state.intentExistsInOtherApplication(row.data.name) && !state.isOtherNamespaceIntent(row.data)"
matTooltip="Mandatory states"
>
<br />
Expand Down Expand Up @@ -263,7 +264,7 @@ <h4 class="title">No Intent found</h4>
*nbTreeGridCellDef="let row"
class="actions"
>
<div *ngIf="!row.data.expandable">
<div *ngIf="!row.data.expandable && !state.isOtherNamespaceIntent(row.data)">
<button
nbButton
outline
Expand Down
2 changes: 1 addition & 1 deletion nlp/admin/web/src/app/intents/intents.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class IntentsComponent implements OnInit {
) {}

ngOnInit() {
this.state.currentIntentsCategories.subscribe((it) => {
this.state.currentNamespaceIntentsCategories.subscribe((it) => {
this.nodes = Array.from(it, (element) => {
return {
expanded: element.category === 'default',
Expand Down
2 changes: 1 addition & 1 deletion nlp/admin/web/src/app/logs/log-stats.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
>
<nb-option value="_all_">All</nb-option>
<nb-option-group
*ngFor="let category of state.currentIntentsCategories | async"
*ngFor="let category of state.currentNamespaceIntentsCategories | async"
[title]="category.category"
>
<nb-option
Expand Down
11 changes: 9 additions & 2 deletions nlp/admin/web/src/app/model/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class Application {
public supportSubEntities: boolean,
public unknownIntentThreshold: number,
public normalizeText: boolean,
public namespaceIntents: Intent[],
public _id?: string
) {}

Expand All @@ -46,10 +47,15 @@ export class Application {
this.supportSubEntities,
this.unknownIntentThreshold,
this.normalizeText,
this.namespaceIntents,
this._id
);
}

isOtherNamespaceIntent(intent: Intent) : boolean {
return this.namespaceIntents.findIndex(i => i.namespace === intent.namespace && i.name === intent.name) !== -1;
}

removeIntentById(id: string) {
this.intents.forEach((e, i) => {
if (e._id === id) {
Expand All @@ -69,7 +75,7 @@ export class Application {
}

intentById(id: string): Intent {
return this.intents.find((i) => i._id === id);
return this.intents.find((i) => i._id === id)
}

supportLocale(locale: string): boolean {
Expand Down Expand Up @@ -110,7 +116,8 @@ export class Application {
const result = Object.assign(value, json, {
intents: Intent.fromJSONArray(json.intents),
nlpEngineType: NlpEngineType.fromJSON(json.nlpEngineType),
label: json.label || json.name
label: json.label || json.name,
namespaceIntents: Intent.fromJSONArray(json.namespaceIntents),
});

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<tock-search-filter
[groups]="intentGroups()"
(filterChange)="changeIntentFilter($event)"
[selectedValue]="selectedValueLabel"
[selectedValue]="selectedIntentLabel"
[activeFirst]="true"
[cleanupIfSelected]="true"
name="Intent"
Expand Down Expand Up @@ -244,6 +244,7 @@
Unknown
</button>
<button
[disabled]="state.isOtherNamespaceIntent(selectedIntent)"
nbButton
status="primary"
size="small"
Expand All @@ -254,6 +255,7 @@
Validate
</button>
<button
[disabled]="state.isOtherNamespaceIntent(selectedIntent)"
nbButton
outline
status="primary"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export class SentenceAnalysisComponent implements OnInit {
intentBeforeClassification: string;
UNKNOWN_INTENT_FILTER = new FilterOption('tock:unknown', 'Unknown');
intentId: string;
selectedValueLabel: string;
selectedIntent:Intent;
selectedIntentLabel: string;

constructor(
public state: StateService,
Expand All @@ -66,9 +67,11 @@ export class SentenceAnalysisComponent implements OnInit {
ngOnInit() {
this.intentBeforeClassification = this.sentence.classification.intentId;
if (this.intentBeforeClassification === this.UNKNOWN_INTENT_FILTER.value) {
this.selectedValueLabel = this.UNKNOWN_INTENT_FILTER.label;
this.selectedIntent = null;
this.selectedIntentLabel = this.UNKNOWN_INTENT_FILTER.label;
} else {
this.selectedValueLabel = this.state.findIntentById(this.intentBeforeClassification).name;
this.selectedIntent = this.state.findSharedNamespaceIntentById(this.intentBeforeClassification);
this.selectedIntentLabel = this.selectedIntent.name;
}
if (this.minimalView) {
setTimeout((_) => {
Expand All @@ -80,7 +83,8 @@ export class SentenceAnalysisComponent implements OnInit {
changeIntentFilter = (intentId: string) => {
if (intentId && this.sentence.classification.intentId !== intentId) {
this.sentence.classification.intentId = intentId;
this.selectedValueLabel = this.state.findIntentById(intentId).name;
this.selectedIntent = this.state.findIntentById(intentId);
this.selectedIntentLabel = this.selectedIntent.name;
this.onIntentChange();
}
};
Expand Down Expand Up @@ -268,7 +272,8 @@ export class SentenceAnalysisComponent implements OnInit {
)
.subscribe(
(intent) => {
this.selectedValueLabel = intent.intentLabel();
this.selectedIntent = intent;
this.selectedIntentLabel = intent.intentLabel();
this.state.addIntent(intent);
this.sentence.classification.intentId = intent._id;
this.onIntentChange();
Expand Down
2 changes: 1 addition & 1 deletion nlp/build-model-worker/src/main/kotlin/BuildModelWorker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class BuildModelWorker {
logger.trace { "New sentences : ${sentences.map { it.text }}" }

front.updateIntentsModelForApplication(sentences, app, key.language, app.nlpEngineType, onlyIfNotExists)
sentences.groupBy { it.classification.intentId }.forEach { intentId, intentSentences ->
sentences.groupBy { it.classification.intentId }.forEach { (intentId, intentSentences) ->
logger.info { "start model update for ${app.name}, intent $intentId and ${key.language}" }
front.updateEntityModelForIntent(
intentSentences,
Expand Down
Loading

0 comments on commit fc0e357

Please sign in to comment.