botbuilder-dialogs-adaptive
Version:
Rule system for the Microsoft BotBuilder dialog system.
176 lines (154 loc) • 4.7 kB
text/typescript
/**
* @module botbuilder-dialogs-adaptive
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
/**
* Extended information about an entity including $instance data.
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
export interface EntityInfo {
/**
* Name of entity.
*/
name: string;
/**
* Value of entity.
*/
value: any;
/**
* Value of property if any.
*/
property: string;
/**
* Operation to apply to entity.
*/
operation: string;
/**
* Position where entity starts in utterance.
*/
start: number;
/**
* Position where entity ends in utterance.
*/
end: number;
/**
* Score (0-1.0) of entity.
*/
score: number;
/**
* Original text that led to entity.
*/
text: string;
/**
* Root entity where this entity was found.
*/
rootEntity: string;
/**
* Type of entity.
*/
type: string;
/**
* Relative priority of entity compared to other entities with 0 being highest priority.
*/
priority: number;
/**
* How much (0-1.0) of the original utterance is covered by entity.
*/
coverage: number;
/**
* Event counter when entity was recognized.
*/
whenRecognized: number;
}
/**
* @private
*/
export interface NormalizedEntityInfos {
[name: string]: Partial<EntityInfo>[];
}
/**
* Extended information about an entity including $instance data.
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
export class EntityInfo {
/**
* Print an entity as a string.
*
* @param source Source entity.
* @returns A string that represents the current object.
*/
static toString(source: Partial<EntityInfo>): string {
return `${source.name}:${source.value} P${source.priority} ${source.score} ${source.coverage}`;
}
/**
* Returns true if entities share text in utterance.
*
* @param source Source entity.
* @param entity Entity to compare.
* @returns True if entities share text in utterance, otherwise false.
*/
static overlaps(source: Partial<EntityInfo>, entity: Partial<EntityInfo>): boolean {
return source.start <= entity.end && source.end >= entity.start;
}
/**
* Returns true if entities come from exactly the same text in the utterance.
*
* @param source Source entity.
* @param entity Entity to compare.
* @returns True if entities come from the exactly same text in utterance, otherwise false.
*/
static alternative(source: Partial<EntityInfo>, entity: Partial<EntityInfo>): boolean {
return source.start == entity.start && source.end == entity.end;
}
/**
* Returns true entity text completely includes another entity text.
*
* @param source Source entity.
* @param entity Entity to compare.
* @returns True if the entity text completely includes another entity text, otherwise false.
*/
static covers(source: Partial<EntityInfo>, entity: Partial<EntityInfo>): boolean {
return (
source.start <= entity.start &&
source.end >= entity.end &&
source.end - source.start > entity.end - entity.start
);
}
/**
* Returns true if entities share the same root.
*
* @param source Source entity.
* @param entity Entity to compare.
* @returns True if entities share the same root, otherwise false.
*/
static sharesRoot(source: Partial<EntityInfo>, entity: Partial<EntityInfo>): boolean {
return source.rootEntity === entity.rootEntity;
}
/**
* Returns true if entities are the same.
*
* @param source Source entity.
* @param entity Entity to compare.
* @returns True if entities are the same, otherwise false.
*/
static isSameEntity(source: Partial<EntityInfo>, entity: Partial<EntityInfo>): boolean {
return EntityInfo.sharesRoot(source, entity) && EntityInfo.alternative(source, entity);
}
/**
* @private
* Remove any entities that overlap a selected entity.
* @param source Source entity.
* @param entities Normalized set of entities to modify.
*/
static removeOverlappingEntities(source: EntityInfo, entities: NormalizedEntityInfos): void {
for (const name in entities) {
const infos = entities[name];
if (Array.isArray(infos)) {
entities[name] = infos.filter((e) => !EntityInfo.overlaps(e, source));
}
}
}
}