Skip to content

Commit

Permalink
port: [#6434] Priority broken for RegexRecognizer (#6435) (#4323)
Browse files Browse the repository at this point in the history
* Consider intents' priority to get top intent

* Add unit test
  • Loading branch information
ceciliaavila authored Sep 13, 2022
1 parent a7b90f3 commit fdf7762
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 8 deletions.
34 changes: 29 additions & 5 deletions libraries/botbuilder-dialogs-adaptive/src/adaptiveDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import isEqual from 'lodash/isEqual';
import { ActionContext } from './actionContext';
import { AdaptiveDialogState } from './adaptiveDialogState';
import { AdaptiveEvents } from './adaptiveEvents';
import { OnCondition } from './conditions';
import { OnCondition, OnIntent } from './conditions';
import { DialogSetConverter, LanguageGeneratorConverter, RecognizerConverter } from './converters';
import { EntityAssignment } from './entityAssignment';
import { EntityAssignmentComparer } from './entityAssignmentComparer';
Expand Down Expand Up @@ -655,11 +655,35 @@ export class AdaptiveDialog<O extends object = {}> extends DialogContainer<O> im
this._recognizerSet.recognizers.push(new ValueRecognizer());
}
const recognized = await this._recognizerSet.recognize(actionContext, activity);
const { intent } = getTopScoringIntent(recognized);
for (const key in recognized.intents) {
if (key !== intent) {
delete recognized[key];

const intents = Object.entries(recognized.intents);

if (intents.length > 0) {
// Score
// Gathers all the intents with the highest Score value.
const scoreSorted = intents.sort(([, a], [, b]) => b.score - a.score);
const [[, firstItemScore]] = scoreSorted;
const topIntents = scoreSorted.filter(([, e]) => e.score == firstItemScore.score);

// Priority
// Gathers the Intent with the highest Priority (0 being the highest).
// Note: this functionality is based on the FirstSelector.SelectAsync method.
let [topIntent] = topIntents;

if (topIntents.length > 1) {
let highestPriority = Number.MAX_SAFE_INTEGER;
for (const [key, intent] of topIntents) {
const [triggerIntent] = this.triggers.filter((x) => x instanceof OnIntent && x.intent == key);
const priority = triggerIntent.currentPriority(actionContext);
if (priority >= 0 && priority < highestPriority) {
topIntent = [key, intent];
highestPriority = priority;
}
}
}

const [key, value] = topIntent;
recognized.intents = { [key]: value };
}
return recognized;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class RegexRecognizer extends AdaptiveRecognizer implements RegexRecogniz
const regexp = intentPattern.regex;
while ((matched = regexp.exec(text))) {
matches.push(matched);
if (regexp.lastIndex == text.length) {
if (regexp.lastIndex == text.length || !regexp.lastIndex) {
break; // to avoid infinite loop
}
}
Expand Down Expand Up @@ -135,8 +135,6 @@ export class RegexRecognizer extends AdaptiveRecognizer implements RegexRecogniz
});
}
});

break;
}

if (this.entities) {
Expand Down
58 changes: 58 additions & 0 deletions libraries/botbuilder-dialogs-adaptive/tests/adaptiveDialog.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,62 @@ describe('AdaptiveDialog', function () {
.assertReply('passed')
.startTest();
});

it('Get top intent using score and priority', async function () {
const priorityDialog = new AdaptiveDialog('priority').configure({
autoEndDialog: false,
recognizer: new RegexRecognizer().configure({
intents: [
{
intent: 'cancel',
pattern: '^(?:cancel|quit|stop|end)',
},
{
intent: 'default',
pattern: '.',
},
{
intent: 'help',
pattern: '^(?:support|advice|help|\\?)',
},
],
}),
triggers: [
new OnIntent().configure({
intent: 'cancel',
priority: 0,
actions: [new SendActivity('Cancel intent recognized')],
}),
new OnIntent().configure({
intent: 'default',
priority: 999,
actions: [new SendActivity('Default intent recognized')],
}),
new OnIntent().configure({
intent: 'help',
priority: 0,
actions: [new SendActivity('Help intent recognized')],
}),
],
});

const dm = new DialogManager(priorityDialog);

const adapter = new TestAdapter(async (context) => {
await dm.onTurn(context);
});
const storage = new MemoryStorage();
useBotState(adapter, new ConversationState(storage), new UserState(storage));

await adapter
.send('help')
.assertReply('Help intent recognized')
.send('?')
.assertReply('Help intent recognized')
.send('cancel')
.assertReply('Cancel intent recognized')
.send('random-text')
.assertReply('Default intent recognized')
.startTest();
});
});

0 comments on commit fdf7762

Please sign in to comment.