Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 40549ca

Browse files
authored
add children entities (#1278)
1 parent bf1f054 commit 40549ca

File tree

2 files changed

+153
-84
lines changed

2 files changed

+153
-84
lines changed

packages/orchestratorlib/src/orchestratorhelper.ts

Lines changed: 76 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ export class OrchestratorHelper {
7575
fs.unlinkSync(filePath);
7676
}
7777

78-
public static label(name: string, offset: number, length: number): {entity: string; startPos: number; endPos: number} {
79-
return {entity: name, startPos: offset, endPos: offset + length - 1};
80-
}
81-
8278
public static createDteContent(utteranceLabelsMap: Map<string, Set<string>>) {
8379
const labelUtteranceMap: Map<string, string> = new Map<string, string>();
8480
// eslint-disable-next-line guard-for-in
@@ -761,15 +757,16 @@ export class OrchestratorHelper {
761757
});
762758
}
763759
// eslint-disable-next-line no-prototype-builtins
764-
if (jsonBluExample.hasOwnProperty('entities')) { // ---- NOTE-TODO-NEED-TO-REEXAMINE-AFTER-BLU-IS-IMPLEMENTED ----
760+
if (jsonBluExample.hasOwnProperty('entities')) {
765761
const jsonBluExampleEntities: any[] = jsonBluExample.entities;
766762
jsonBluExampleEntities.forEach((jsonBluExampleEntity: any) => {
767763
const jsonBluExampleEntityLabel: string = jsonBluExampleEntity.entity;
768764
const jsonBluExampleEntityOffset: number = jsonBluExampleEntity.offset;
769765
const jsonBluExampleEntityLength: number = jsonBluExampleEntity.length;
766+
const newEntityLabel: Label = Label.newEntityLabel(jsonBluExampleEntityLabel, jsonBluExampleEntityOffset, jsonBluExampleEntityLength);
770767
OrchestratorHelper.addNewEntityLabelObjectUtterance(
771768
utterance,
772-
Label.newEntityLabel(jsonBluExampleEntityLabel, jsonBluExampleEntityOffset, jsonBluExampleEntityLength),
769+
newEntityLabel,
773770
utteranceEntityLabelsMap,
774771
utteranceEntityLabelDuplicateMap);
775772
});
@@ -859,9 +856,10 @@ export class OrchestratorHelper {
859856
} else if (labelType === LabelType.Entity) {
860857
const labelSpanOffset: number = label.span.offset;
861858
const labelSpanLength: number = label.span.length;
862-
OrchestratorHelper.addNewEntityLabelUtterance(
859+
const newEntityLabel: Label = Label.newEntityLabel(labelName, labelSpanOffset, labelSpanLength);
860+
OrchestratorHelper.addNewEntityLabelObjectUtterance(
863861
utterance,
864-
this.label(labelName, labelSpanOffset, labelSpanLength),
862+
newEntityLabel,
865863
utteranceEntityLabelsMap,
866864
utteranceEntityLabelDuplicateMap);
867865
}
@@ -967,31 +965,93 @@ export class OrchestratorHelper {
967965

968966
// ---- NOTE-TO-REFACTOR ----
969967
// eslint-disable-next-line max-params
970-
static addNewEntityLabelUtterance(
968+
static addNewEntityLabelUtteranceTraversal(
971969
utterance: string,
970+
existingEntityLabels: Label[],
972971
entityEntry: any,
973972
utteranceEntityLabelsMap: Map<string, Label[]>,
974-
utteranceEntityLabelDuplicateMap: Map<string, Label[]>): void {
975-
let existingEntityLabels: Label[] = [];
973+
utteranceEntityLabelDuplicateMap: Map<string, Label[]>,
974+
entityLabelPrefix: string = ''): void {
976975
try {
977-
// eslint-disable-next-line no-prototype-builtins
978-
if (utteranceEntityLabelsMap.has(utterance)) {
979-
existingEntityLabels = utteranceEntityLabelsMap.get(utterance) as Label[];
980-
}
981-
const entityName: string = entityEntry.entity;
976+
let entityName: string = entityEntry.entity;
982977
const startPos: number = Number(entityEntry.startPos);
983978
const endPos: number = Number(entityEntry.endPos);
984979
// const entityMention: string = entityEntry.text;
985980
if (Utility.isEmptyString(entityName) || (startPos === undefined) || (endPos === undefined)) {
986981
Utility.debuggingThrow(`EMPTY entityName: '${entityName}', startPos='${startPos}', endPos='${endPos}', entityEntry='${entityEntry}', utterance='${utterance}'`);
987982
}
983+
if (!UtilityDispatcher.isEmptyString(entityLabelPrefix)) {
984+
entityName = `${entityLabelPrefix}:${entityName}`;
985+
}
986+
UtilityDispatcher.debuggingLog1(
987+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal()-entityName', entityName);
988+
UtilityDispatcher.debuggingLog1(
989+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal()-startPos', startPos);
990+
UtilityDispatcher.debuggingLog1(
991+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal()-endPos', endPos);
992+
UtilityDispatcher.debuggingLog1(
993+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-utteranceEntityLabelsMap-B', UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap]));
994+
UtilityDispatcher.debuggingLog1(
995+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-utteranceEntityLabelsMap.size-B', utteranceEntityLabelsMap.size);
996+
UtilityDispatcher.debuggingLog1(
997+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-[...utteranceEntityLabelsMap].length-B', [...utteranceEntityLabelsMap].length);
988998
const entityLabel: Label = Label.newEntityLabelByPosition(entityName, startPos, endPos);
989999
if (Utility.isEmptyGenericArray(existingEntityLabels)) {
9901000
existingEntityLabels = [entityLabel];
9911001
utteranceEntityLabelsMap.set(utterance, existingEntityLabels);
1002+
UtilityDispatcher.debuggingLog1(
1003+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-utteranceEntityLabelsMap-I', UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap]));
1004+
UtilityDispatcher.debuggingLog1(
1005+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-utteranceEntityLabelsMap.size-I', utteranceEntityLabelsMap.size);
1006+
UtilityDispatcher.debuggingLog1(
1007+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-[...utteranceEntityLabelsMap].length-I', [...utteranceEntityLabelsMap].length);
9921008
} else if (!OrchestratorHelper.addUniqueEntityLabelArray(entityLabel, existingEntityLabels)) {
9931009
Utility.insertStringLabelPairToStringIdLabelSetNativeMap(utterance, entityLabel, utteranceEntityLabelDuplicateMap);
9941010
}
1011+
UtilityDispatcher.debuggingLog1(
1012+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-utteranceEntityLabelsMap-A', UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap]));
1013+
UtilityDispatcher.debuggingLog1(
1014+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-utteranceEntityLabelsMap.size-A', utteranceEntityLabelsMap.size);
1015+
UtilityDispatcher.debuggingLog1(
1016+
'OrchestratorHelper.addNewEntityLabelUtteranceTraversal(),-[...utteranceEntityLabelsMap].length-A', [...utteranceEntityLabelsMap].length);
1017+
// eslint-disable-next-line no-prototype-builtins
1018+
if (entityEntry.hasOwnProperty('children')) {
1019+
entityEntry.children.forEach((childEntityEntry: any) => {
1020+
OrchestratorHelper.addNewEntityLabelUtteranceTraversal(
1021+
utterance,
1022+
existingEntityLabels,
1023+
childEntityEntry,
1024+
utteranceEntityLabelsMap,
1025+
utteranceEntityLabelDuplicateMap,
1026+
entityName);
1027+
});
1028+
}
1029+
} catch (error) {
1030+
Utility.debuggingLog(`EXCEPTION calling addNewEntityLabelUtteranceTraversal(), error='${error}', entityEntry='${entityEntry}', utterance='${utterance}', existingEntityLabels='${existingEntityLabels}'`);
1031+
throw error;
1032+
}
1033+
}
1034+
1035+
// ---- NOTE-TO-REFACTOR ----
1036+
// eslint-disable-next-line max-params
1037+
static addNewEntityLabelUtterance(
1038+
utterance: string,
1039+
entityEntry: any,
1040+
utteranceEntityLabelsMap: Map<string, Label[]>,
1041+
utteranceEntityLabelDuplicateMap: Map<string, Label[]>): void {
1042+
let existingEntityLabels: Label[] = [];
1043+
try {
1044+
// eslint-disable-next-line no-prototype-builtins
1045+
if (utteranceEntityLabelsMap.has(utterance)) {
1046+
existingEntityLabels = utteranceEntityLabelsMap.get(utterance) as Label[];
1047+
}
1048+
OrchestratorHelper.addNewEntityLabelUtteranceTraversal(
1049+
utterance,
1050+
existingEntityLabels,
1051+
entityEntry,
1052+
utteranceEntityLabelsMap,
1053+
utteranceEntityLabelDuplicateMap,
1054+
'');
9951055
} catch (error) {
9961056
Utility.debuggingLog(`EXCEPTION calling addNewEntityLabelUtterance(), error='${error}', entityEntry='${entityEntry}', utterance='${utterance}', existingEntityLabels='${existingEntityLabels}'`);
9971057
throw error;
@@ -1049,70 +1109,6 @@ export class OrchestratorHelper {
10491109
return false;
10501110
}
10511111

1052-
// ---- NOTE-TO-REFACTOR ----
1053-
// eslint-disable-next-line max-params
1054-
static addNewLabelUtteranceToObjectDictionary(
1055-
utterance: string,
1056-
label: string,
1057-
hierarchicalLabel: string,
1058-
utteranceLabelsMap: {[id: string]: string[]},
1059-
utteranceLabelDuplicateMap: Map<string, Set<string>>): void {
1060-
const isHierarchicalLabel: boolean = !Utility.isEmptyString(hierarchicalLabel);
1061-
let existingLabels: string[] = [];
1062-
try {
1063-
// eslint-disable-next-line no-prototype-builtins
1064-
if (utteranceLabelsMap.hasOwnProperty(utterance)) {
1065-
existingLabels = utteranceLabelsMap[utterance];
1066-
}
1067-
if (!Utility.isEmptyStringArray(existingLabels)) {
1068-
if (isHierarchicalLabel) {
1069-
if (!OrchestratorHelper.addUniqueLabelToArray(hierarchicalLabel, existingLabels)) {
1070-
Utility.insertStringPairToStringIdStringSetNativeMap(utterance, hierarchicalLabel, utteranceLabelDuplicateMap);
1071-
}
1072-
} else if (!OrchestratorHelper.addUniqueLabelToArray(label, existingLabels)) {
1073-
Utility.insertStringPairToStringIdStringSetNativeMap(utterance, label, utteranceLabelDuplicateMap);
1074-
}
1075-
} else if (isHierarchicalLabel) {
1076-
utteranceLabelsMap[utterance] = [hierarchicalLabel];
1077-
} else {
1078-
utteranceLabelsMap[utterance] = [label];
1079-
}
1080-
} catch (error) {
1081-
Utility.debuggingLog(`EXCEPTION calling addNewLabelUtteranceToObjectDictionary(), error='${error}', label='${label}', utterance='${utterance}', hierarchicalLabel='${hierarchicalLabel}', isHierarchicalLabel='${isHierarchicalLabel}', existingLabels='${existingLabels}'`);
1082-
throw error;
1083-
}
1084-
}
1085-
1086-
// ---- NOTE-TO-REFACTOR ----
1087-
// eslint-disable-next-line max-params
1088-
static addNewEntityLabelUtteranceToObjectDictionary(
1089-
utterance: string,
1090-
entityEntry: any,
1091-
utteranceEntityLabelsMap: {[id: string]: Label[]},
1092-
utteranceEntityLabelDuplicateMap: Map<string, Label[]>): void {
1093-
let existingEntityLabels: Label[] = [];
1094-
try {
1095-
// eslint-disable-next-line no-prototype-builtins
1096-
if (utteranceEntityLabelsMap.hasOwnProperty(utterance)) {
1097-
existingEntityLabels = utteranceEntityLabelsMap[utterance];
1098-
}
1099-
const entityName: string = entityEntry.entity;
1100-
const startPos: number = Number(entityEntry.startPos);
1101-
const endPos: number = Number(entityEntry.endPos);
1102-
// const entityMention: string = entityEntry.text;
1103-
const entityLabel: Label = Label.newEntityLabelByPosition(entityName, startPos, endPos);
1104-
if (Utility.isEmptyGenericArray(existingEntityLabels)) {
1105-
existingEntityLabels = [entityLabel];
1106-
utteranceEntityLabelsMap[utterance] = existingEntityLabels;
1107-
} else if (!OrchestratorHelper.addUniqueEntityLabelArray(entityLabel, existingEntityLabels)) {
1108-
Utility.insertStringLabelPairToStringIdLabelSetNativeMap(utterance, entityLabel, utteranceEntityLabelDuplicateMap);
1109-
}
1110-
} catch (error) {
1111-
Utility.debuggingLog(`EXCEPTION calling addNewEntityLabelUtteranceToObjectDictionary(), error='${error}', entityEntry='${entityEntry}', utterance='${utterance}', existingEntityLabels='${existingEntityLabels}'`);
1112-
throw error;
1113-
}
1114-
}
1115-
11161112
// ---- NOTE-TO-REFACTOR ----
11171113
static addUniqueLabelToArray(newLabel: string, labels: string[]): boolean {
11181114
try {

packages/orchestratorlib/test/orchestratorhelper.test.ts

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {OrchestratorHelper} from '../src/orchestratorhelper';
1717
import {DictionaryMapUtility} from '@microsoft/bf-dispatcher';
1818

1919
import {Utility} from '../src/utility';
20+
import {Utility as UtilityDispatcher} from '@microsoft/bf-dispatcher';
2021
import {UnitTestHelper} from './utility.test';
2122

2223
describe('Test Suite - orchestratorhelper', () => {
@@ -85,7 +86,7 @@ describe('Test Suite - orchestratorhelper', () => {
8586
utteranceEntityLabelDuplicateMap);
8687
});
8788
Utility.debuggingLog(
88-
`utteranceEntityLabelsMap=${Utility.jsonStringify(utteranceEntityLabelsMap)}`);
89+
`utteranceEntityLabelsMap=${UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap])}`);
8990
let utteranceEntityLabelsMapSize: number = utteranceEntityLabelsMap.size;
9091
assert.ok(entityObject.text === 'Seattle');
9192
assert.ok(utteranceEntityLabelsMapSize === 1);
@@ -109,7 +110,7 @@ describe('Test Suite - orchestratorhelper', () => {
109110
utteranceEntityLabelDuplicateMap);
110111
});
111112
Utility.debuggingLog(
112-
`utteranceEntityLabelsMap=${Utility.jsonStringify(utteranceEntityLabelsMap)}`);
113+
`utteranceEntityLabelsMap=${UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap])}`);
113114
utteranceEntityLabelsMapSize = utteranceEntityLabelsMap.size;
114115
assert.ok(entityObject.text === 'Paris');
115116
assert.ok(entityObjectSecond.text === 'Berlin');
@@ -130,7 +131,7 @@ describe('Test Suite - orchestratorhelper', () => {
130131
utteranceEntityLabelDuplicateMap);
131132
});
132133
Utility.debuggingLog(
133-
`utteranceEntityLabelsMap=${Utility.jsonStringify(utteranceEntityLabelsMap)}`);
134+
`utteranceEntityLabelsMap=${UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap])}`);
134135
utteranceEntityLabelsMapSize = utteranceEntityLabelsMap.size;
135136
assert.ok(entityObject.text === 'Paris');
136137
assert.ok(entityObjectSecond.text === 'Berlin');
@@ -153,7 +154,7 @@ describe('Test Suite - orchestratorhelper', () => {
153154
utteranceEntityLabelDuplicateMap);
154155
});
155156
Utility.debuggingLog(
156-
`utteranceEntityLabelsMap=${Utility.jsonStringify(utteranceEntityLabelsMap)}`);
157+
`utteranceEntityLabelsMap=${UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap])}`);
157158
utteranceEntityLabelsMapSize = utteranceEntityLabelsMap.size;
158159
assert.ok(entityObject.text === 'Paris');
159160
assert.ok(entityObjectSecond.text === 'Berlin');
@@ -352,6 +353,78 @@ describe('Test Suite - orchestratorhelper', () => {
352353
assert.ok((utteranceEntityLabelDuplicateMap.get(utterance1) as Label[]).length === 3,
353354
`(utteranceEntityLabelDuplicateMap.get(utterance1) as Label[]).length=${(utteranceEntityLabelDuplicateMap.get(utterance1) as Label[]).length}`);
354355
});
356+
it('Test.0201 OrchestratorHelper.getJsonIntentsEntitiesUtterances() with child entity labels', function () {
357+
Utility.resetFlagToPrintDebuggingLogToConsole(UnitTestHelper.getDefaultUnitTestDebuggingLogFlag());
358+
this.timeout(UnitTestHelper.getDefaultUnitTestTimeout());
359+
const utterance: string = 'traveling from Paris to Berlin';
360+
const jsonObjectArray: {
361+
'text': string;
362+
'intents': string[];
363+
'entities': {
364+
'entity': string;
365+
'startPos': number;
366+
'endPos': number;
367+
'children': {
368+
'entity': string;
369+
'startPos': number;
370+
'endPos': number;
371+
}[];
372+
}[];
373+
}[] = [
374+
{
375+
text: utterance,
376+
intents: ['Travel'],
377+
entities: [
378+
{
379+
entity: 'trip',
380+
startPos: 15,
381+
endPos: 29,
382+
children: [
383+
{
384+
entity: 'origin',
385+
startPos: 15,
386+
endPos: 19,
387+
},
388+
{
389+
entity: 'destination',
390+
startPos: 24,
391+
endPos: 29,
392+
},
393+
],
394+
},
395+
],
396+
},
397+
];
398+
const utteranceLabelsMap: Map<string, Set<string>> = new Map<string, Set<string>>();
399+
const utteranceLabelDuplicateMap: Map<string, Set<string>> = new Map<string, Set<string>>();
400+
const utteranceEntityLabelsMap: Map<string, Label[]> = new Map<string, Label[]>();
401+
const utteranceEntityLabelDuplicateMap: Map<string, Label[]> = new Map<string, Label[]>();
402+
OrchestratorHelper.getJsonIntentsEntitiesUtterances(
403+
jsonObjectArray,
404+
'',
405+
utteranceLabelsMap,
406+
utteranceLabelDuplicateMap,
407+
utteranceEntityLabelsMap,
408+
utteranceEntityLabelDuplicateMap);
409+
const utteranceLabelDuplicateMapSize: number = utteranceLabelDuplicateMap.size;
410+
const utteranceEntityLabelDuplicateMapSize: number = utteranceEntityLabelDuplicateMap.size;
411+
Utility.debuggingLog(
412+
`utteranceLabelsMap=${DictionaryMapUtility.jsonStringifyStringKeyGenericSetNativeMapArrayValue(utteranceLabelsMap)}`);
413+
Utility.debuggingLog(
414+
`utteranceEntityLabelsMap=${UtilityDispatcher.jsonStringify([...utteranceEntityLabelsMap])}`);
415+
assert.ok(utteranceLabelsMap.size === 1,
416+
`utteranceLabelsMap.size=${utteranceLabelsMap.size}`);
417+
assert.ok(utteranceLabelDuplicateMapSize === 0,
418+
`utteranceLabelDuplicateMapSize=${utteranceLabelDuplicateMapSize}`);
419+
assert.ok(utteranceEntityLabelsMap.size === 1,
420+
`utteranceEntityLabelsMap.size=${utteranceEntityLabelsMap.size}`);
421+
assert.ok(utteranceEntityLabelDuplicateMapSize === 0,
422+
`utteranceEntityLabelDuplicateMapSize=${utteranceEntityLabelDuplicateMapSize}`);
423+
assert.ok((utteranceLabelsMap.get(utterance) as Set<string>).size === 1,
424+
`(utteranceLabelsMap.get(utterance) as Set<string>).size=${(utteranceLabelsMap.get(utterance) as Set<string>).size}`);
425+
assert.ok((utteranceEntityLabelsMap.get(utterance) as Label[]).length === 3,
426+
`(utteranceEntityLabelsMap.get(utterance) as Label[]).length=${(utteranceEntityLabelsMap.get(utterance) as Label[]).length}`);
427+
});
355428

356429
it('Test.0300 OrchestratorHelper.getJsonIntentEntityScoresUtterances()', function () {
357430
Utility.resetFlagToPrintDebuggingLogToConsole(UnitTestHelper.getDefaultUnitTestDebuggingLogFlag());

0 commit comments

Comments
 (0)