mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
feat: refactor current implementation
This commit is contained in:
parent
1281c9e23b
commit
392649f08a
@ -37,7 +37,6 @@ import { NlpValueRepository } from '@/nlp/repositories/nlp-value.repository';
|
||||
import { NlpEntityModel } from '@/nlp/schemas/nlp-entity.schema';
|
||||
import { NlpSampleEntityModel } from '@/nlp/schemas/nlp-sample-entity.schema';
|
||||
import { NlpValueModel } from '@/nlp/schemas/nlp-value.schema';
|
||||
import { NlpCacheMap } from '@/nlp/schemas/types';
|
||||
import { NlpEntityService } from '@/nlp/services/nlp-entity.service';
|
||||
import { NlpValueService } from '@/nlp/services/nlp-value.service';
|
||||
import { PluginService } from '@/plugins/plugins.service';
|
||||
@ -53,6 +52,8 @@ import {
|
||||
blockProductListMock,
|
||||
blocks,
|
||||
mockModifiedNlpBlock,
|
||||
mockModifiedNlpBlockOne,
|
||||
mockModifiedNlpBlockTwo,
|
||||
mockNlpBlock,
|
||||
mockNlpPatternsSetOne,
|
||||
mockNlpPatternsSetThree,
|
||||
@ -79,7 +80,6 @@ import { Category, CategoryModel } from '../schemas/category.schema';
|
||||
import { LabelModel } from '../schemas/label.schema';
|
||||
import { FileType } from '../schemas/types/attachment';
|
||||
import { StdOutgoingListMessage } from '../schemas/types/message';
|
||||
import { NlpPattern } from '../schemas/types/pattern';
|
||||
|
||||
import { CategoryRepository } from './../repositories/category.repository';
|
||||
import { BlockService } from './block.service';
|
||||
@ -324,55 +324,50 @@ describe('BlockService', () => {
|
||||
blockGetStarted,
|
||||
);
|
||||
expect(result).toEqual([
|
||||
{
|
||||
entity: 'intent',
|
||||
match: 'value',
|
||||
value: 'greeting',
|
||||
},
|
||||
{
|
||||
entity: 'firstname',
|
||||
match: 'entity',
|
||||
},
|
||||
[
|
||||
{
|
||||
entity: 'intent',
|
||||
match: 'value',
|
||||
value: 'greeting',
|
||||
},
|
||||
{
|
||||
entity: 'firstname',
|
||||
match: 'entity',
|
||||
},
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return undefined when it does not match nlp patterns', () => {
|
||||
it('should return empty array when it does not match nlp patterns', () => {
|
||||
const result = blockService.matchNLP(nlpEntitiesGreeting, {
|
||||
...blockGetStarted,
|
||||
patterns: [[{ entity: 'lastname', match: 'value', value: 'Belakhel' }]],
|
||||
});
|
||||
expect(result).toEqual(undefined);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return undefined when unknown nlp patterns', () => {
|
||||
it('should return empty array when unknown nlp patterns', () => {
|
||||
const result = blockService.matchNLP(nlpEntitiesGreeting, {
|
||||
...blockGetStarted,
|
||||
patterns: [[{ entity: 'product', match: 'value', value: 'pizza' }]],
|
||||
});
|
||||
expect(result).toEqual(undefined);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('matchBestNLP', () => {
|
||||
const nlpPenaltyFactor = 2;
|
||||
it('should return the block with the highest NLP score', async () => {
|
||||
jest
|
||||
.spyOn(nlpEntityService, 'getNlpMap')
|
||||
.mockResolvedValue(mockNlpCacheMap);
|
||||
const blocks = [mockNlpBlock, blockGetStarted]; // You can add more blocks with different patterns and scores
|
||||
const matchedPatterns = [mockNlpPatternsSetOne, mockNlpPatternsSetTwo];
|
||||
const nlp = mockNlpEntitiesSetOne;
|
||||
// Spy on calculateBlockScore to check if it's called
|
||||
const calculateBlockScoreSpy = jest.spyOn(
|
||||
blockService,
|
||||
'calculateBlockScore',
|
||||
);
|
||||
const bestBlock = await blockService.matchBestNLP(
|
||||
blocks,
|
||||
matchedPatterns,
|
||||
nlp,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
const bestBlock = await blockService.matchBestNLP(blocks, nlp);
|
||||
|
||||
// Ensure calculateBlockScore was called at least once for each block
|
||||
expect(calculateBlockScoreSpy).toHaveBeenCalledTimes(2); // Called for each block
|
||||
@ -388,19 +383,13 @@ describe('BlockService', () => {
|
||||
.spyOn(nlpEntityService, 'getNlpMap')
|
||||
.mockResolvedValue(mockNlpCacheMap);
|
||||
const blocks = [mockNlpBlock, mockModifiedNlpBlock]; // You can add more blocks with different patterns and scores
|
||||
const matchedPatterns = [mockNlpPatternsSetOne, mockNlpPatternsSetThree];
|
||||
const nlp = mockNlpEntitiesSetOne;
|
||||
// Spy on calculateBlockScore to check if it's called
|
||||
const calculateBlockScoreSpy = jest.spyOn(
|
||||
blockService,
|
||||
'calculateBlockScore',
|
||||
);
|
||||
const bestBlock = await blockService.matchBestNLP(
|
||||
blocks,
|
||||
matchedPatterns,
|
||||
nlp,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
const bestBlock = await blockService.matchBestNLP(blocks, nlp);
|
||||
|
||||
// Ensure calculateBlockScore was called at least once for each block
|
||||
expect(calculateBlockScoreSpy).toHaveBeenCalledTimes(2); // Called for each block
|
||||
@ -408,7 +397,29 @@ describe('BlockService', () => {
|
||||
// Restore the spy after the test
|
||||
calculateBlockScoreSpy.mockRestore();
|
||||
// Assert that the block with the highest NLP score is selected
|
||||
expect(bestBlock).toEqual(mockModifiedNlpBlock);
|
||||
expect(bestBlock).toEqual(mockNlpBlock);
|
||||
});
|
||||
|
||||
it('another case where it should return the block with the highest NLP score applying penalties', async () => {
|
||||
jest
|
||||
.spyOn(nlpEntityService, 'getNlpMap')
|
||||
.mockResolvedValue(mockNlpCacheMap);
|
||||
const blocks = [mockModifiedNlpBlockOne, mockModifiedNlpBlockTwo]; // You can add more blocks with different patterns and scores
|
||||
const nlp = mockNlpEntitiesSetOne;
|
||||
// Spy on calculateBlockScore to check if it's called
|
||||
const calculateBlockScoreSpy = jest.spyOn(
|
||||
blockService,
|
||||
'calculateBlockScore',
|
||||
);
|
||||
const bestBlock = await blockService.matchBestNLP(blocks, nlp);
|
||||
|
||||
// Ensure calculateBlockScore was called at least once for each block
|
||||
expect(calculateBlockScoreSpy).toHaveBeenCalledTimes(3); // Called for each block
|
||||
|
||||
// Restore the spy after the test
|
||||
calculateBlockScoreSpy.mockRestore();
|
||||
// Assert that the block with the highest NLP score is selected
|
||||
expect(bestBlock).toEqual(mockModifiedNlpBlockTwo);
|
||||
});
|
||||
|
||||
it('should return undefined if no blocks match or the list is empty', async () => {
|
||||
@ -416,15 +427,9 @@ describe('BlockService', () => {
|
||||
.spyOn(nlpEntityService, 'getNlpMap')
|
||||
.mockResolvedValue(mockNlpCacheMap);
|
||||
const blocks: BlockFull[] = []; // Empty block array
|
||||
const matchedPatterns: NlpPattern[][] = [];
|
||||
const nlp = mockNlpEntitiesSetOne;
|
||||
|
||||
const bestBlock = await blockService.matchBestNLP(
|
||||
blocks,
|
||||
matchedPatterns,
|
||||
nlp,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
const bestBlock = await blockService.matchBestNLP(blocks, nlp);
|
||||
|
||||
// Assert that undefined is returned when no blocks are available
|
||||
expect(bestBlock).toBeUndefined();
|
||||
@ -432,19 +437,17 @@ describe('BlockService', () => {
|
||||
});
|
||||
|
||||
describe('calculateBlockScore', () => {
|
||||
const nlpPenaltyFactor = 0.9;
|
||||
it('should calculate the correct NLP score for a block', async () => {
|
||||
const score = blockService.calculateBlockScore(
|
||||
jest
|
||||
.spyOn(nlpEntityService, 'getNlpMap')
|
||||
.mockResolvedValue(mockNlpCacheMap);
|
||||
const score = await blockService.calculateBlockScore(
|
||||
mockNlpPatternsSetOne,
|
||||
mockNlpEntitiesSetOne,
|
||||
mockNlpCacheMap,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
const score2 = blockService.calculateBlockScore(
|
||||
const score2 = await blockService.calculateBlockScore(
|
||||
mockNlpPatternsSetTwo,
|
||||
mockNlpEntitiesSetOne,
|
||||
mockNlpCacheMap,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
|
||||
expect(score).toBeGreaterThan(0);
|
||||
@ -453,17 +456,16 @@ describe('BlockService', () => {
|
||||
});
|
||||
|
||||
it('should calculate the correct NLP score for a block and apply penalties ', async () => {
|
||||
const score = blockService.calculateBlockScore(
|
||||
jest
|
||||
.spyOn(nlpEntityService, 'getNlpMap')
|
||||
.mockResolvedValue(mockNlpCacheMap);
|
||||
const score = await blockService.calculateBlockScore(
|
||||
mockNlpPatternsSetOne,
|
||||
mockNlpEntitiesSetOne,
|
||||
mockNlpCacheMap,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
const score2 = blockService.calculateBlockScore(
|
||||
const score2 = await blockService.calculateBlockScore(
|
||||
mockNlpPatternsSetThree,
|
||||
mockNlpEntitiesSetOne,
|
||||
mockNlpCacheMap,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
|
||||
expect(score).toBeGreaterThan(0);
|
||||
@ -472,12 +474,10 @@ describe('BlockService', () => {
|
||||
});
|
||||
|
||||
it('should return 0 if no matching entities are found', async () => {
|
||||
const nlpCacheMap: NlpCacheMap = new Map();
|
||||
const score = blockService.calculateBlockScore(
|
||||
jest.spyOn(nlpEntityService, 'getNlpMap').mockResolvedValue(new Map());
|
||||
const score = await blockService.calculateBlockScore(
|
||||
mockNlpPatternsSetTwo,
|
||||
mockNlpEntitiesSetOne,
|
||||
nlpCacheMap,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
|
||||
expect(score).toBe(0); // No matching entity, so score should be 0
|
||||
|
@ -16,7 +16,7 @@ import { CONSOLE_CHANNEL_NAME } from '@/extensions/channels/console/settings';
|
||||
import { NLU } from '@/helper/types';
|
||||
import { I18nService } from '@/i18n/services/i18n.service';
|
||||
import { LanguageService } from '@/i18n/services/language.service';
|
||||
import { NlpCacheMap, NlpCacheMapValues } from '@/nlp/schemas/types';
|
||||
import { NlpCacheMapValues } from '@/nlp/schemas/types';
|
||||
import { NlpEntityService } from '@/nlp/services/nlp-entity.service';
|
||||
import { PluginService } from '@/plugins/plugins.service';
|
||||
import { PluginType } from '@/plugins/types';
|
||||
@ -37,12 +37,7 @@ import {
|
||||
StdOutgoingEnvelope,
|
||||
StdOutgoingSystemEnvelope,
|
||||
} from '../schemas/types/message';
|
||||
import {
|
||||
isNlpPattern,
|
||||
NlpPattern,
|
||||
NlpPatternMatchResult,
|
||||
PayloadPattern,
|
||||
} from '../schemas/types/pattern';
|
||||
import { NlpPattern, PayloadPattern } from '../schemas/types/pattern';
|
||||
import { Payload, StdQuickReply } from '../schemas/types/quick-reply';
|
||||
import { SubscriberContext } from '../schemas/types/subscriberContext';
|
||||
|
||||
@ -200,36 +195,7 @@ export class BlockService extends BaseService<
|
||||
// This ensures that only blocks with valid matches are kept, and blocks with no matches are excluded,
|
||||
// all while iterating through the list only once.
|
||||
|
||||
const matchesWithPatterns: NlpPatternMatchResult[] =
|
||||
filteredBlocks.reduce<NlpPatternMatchResult[]>((acc, b) => {
|
||||
const matchedPattern = this.matchNLP(nlp, b);
|
||||
|
||||
if (matchedPattern && matchedPattern.length > 0) {
|
||||
acc.push({ block: b, matchedPattern });
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
// @TODO Make nluPenaltyFactor configurable in UI settings
|
||||
const nluPenaltyFactor = 0.95;
|
||||
// Log the matched patterns
|
||||
this.logger.debug(
|
||||
`Matched patterns: ${JSON.stringify(matchesWithPatterns.map((p) => p.matchedPattern))}`,
|
||||
);
|
||||
|
||||
// Proceed with matching the best NLP block
|
||||
if (matchesWithPatterns.length > 0) {
|
||||
const matchedBlocks = matchesWithPatterns.map((m) => m.block);
|
||||
const matchedPatterns = matchesWithPatterns.map(
|
||||
(p) => p.matchedPattern,
|
||||
);
|
||||
block = await this.matchBestNLP(
|
||||
matchedBlocks,
|
||||
matchedPatterns,
|
||||
nlp,
|
||||
nluPenaltyFactor,
|
||||
);
|
||||
}
|
||||
block = await this.matchBestNLP(filteredBlocks, nlp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,7 +308,7 @@ export class BlockService extends BaseService<
|
||||
matchNLP(
|
||||
nlp: NLU.ParseEntities,
|
||||
block: Block | BlockFull,
|
||||
): NlpPattern[] | undefined {
|
||||
): NlpPattern[][] | undefined {
|
||||
// No nlp entities to check against
|
||||
if (nlp.entities.length === 0) {
|
||||
return undefined;
|
||||
@ -355,8 +321,9 @@ export class BlockService extends BaseService<
|
||||
if (nlpPatterns.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Find NLP pattern match based on best guessed entities
|
||||
return nlpPatterns.find((entities: NlpPattern[]) => {
|
||||
return nlpPatterns.filter((entities: NlpPattern[]) => {
|
||||
return entities.every((ev: NlpPattern) => {
|
||||
if (ev.match === 'value') {
|
||||
return nlp.entities.find((e) => {
|
||||
@ -375,59 +342,44 @@ export class BlockService extends BaseService<
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the best-matching block based on NLP pattern scoring.
|
||||
* Matches the provided NLU parsed entities with patterns in a set of blocks and returns
|
||||
* the block with the highest matching score.
|
||||
*
|
||||
* This function evaluates each block by calculating a score derived from its matched NLP patterns,
|
||||
* the parsed NLP entities, and a penalty factor. It compares the scores across all blocks and
|
||||
* returns the one with the highest calculated score.
|
||||
* For each block, it checks the patterns against the NLU parsed entities, calculates
|
||||
* a score for each match, and selects the block with the highest score.
|
||||
*
|
||||
* @param blocks - An array of candidate blocks to evaluate.
|
||||
* @param matchedPatterns - A two-dimensional array of matched NLP patterns corresponding to each block.
|
||||
* @param nlp - The parsed NLP entities used for scoring.
|
||||
* @param nlpPenaltyFactor - A numeric penalty factor applied during scoring to influence block selection.
|
||||
* @returns The block with the highest NLP score, or undefined if no valid block is found.
|
||||
* @param {BlockFull[]} blocks - An array of BlockFull objects representing potential matches.
|
||||
* @param {NLU.ParseEntities} nlp - The NLU parsed entities used for pattern matching.
|
||||
*
|
||||
* @returns {Promise<BlockFull | undefined>} - A promise that resolves to the BlockFull
|
||||
* with the highest match score, or undefined if no matches are found.
|
||||
*/
|
||||
async matchBestNLP(
|
||||
blocks: BlockFull[],
|
||||
matchedPatterns: NlpPattern[][],
|
||||
nlp: NLU.ParseEntities,
|
||||
nlpPenaltyFactor: number,
|
||||
): Promise<BlockFull | undefined> {
|
||||
if (!blocks || blocks.length === 0) return undefined;
|
||||
if (blocks.length === 1) return blocks[0];
|
||||
const scoredBlocks = await Promise.all(
|
||||
blocks.map(async (block) => {
|
||||
const matchedPatterns = this.matchNLP(nlp, block) || [];
|
||||
|
||||
let bestBlock: BlockFull | undefined;
|
||||
let highestScore = 0;
|
||||
const entityNames = this.extractNlpEntityNames(blocks);
|
||||
const uniqueEntityNames = [...new Set(entityNames)];
|
||||
const nlpCacheMap: NlpCacheMap =
|
||||
await this.entityService.getNlpMap(uniqueEntityNames);
|
||||
// Iterate through all blocks and calculate their NLP score
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
const block = blocks[i];
|
||||
const patterns = matchedPatterns[i];
|
||||
// If compatible, calculate the NLP score for this block
|
||||
const nlpScore = this.calculateBlockScore(
|
||||
patterns,
|
||||
nlp,
|
||||
nlpCacheMap,
|
||||
nlpPenaltyFactor,
|
||||
);
|
||||
if (nlpScore > highestScore) {
|
||||
highestScore = nlpScore;
|
||||
bestBlock = block;
|
||||
}
|
||||
}
|
||||
const scores = await Promise.all(
|
||||
matchedPatterns.map((pattern) =>
|
||||
this.calculateBlockScore(pattern, nlp),
|
||||
),
|
||||
);
|
||||
|
||||
if (bestBlock) {
|
||||
this.logger.debug(`Best NLP score obtained: ${highestScore}`);
|
||||
this.logger.debug(`Best block selected:`, {
|
||||
id: bestBlock.id,
|
||||
name: bestBlock.name,
|
||||
});
|
||||
}
|
||||
const maxScore = scores.length > 0 ? Math.max(...scores) : 0;
|
||||
|
||||
return bestBlock;
|
||||
return { block, score: maxScore };
|
||||
}),
|
||||
);
|
||||
|
||||
const best = scoredBlocks.reduce(
|
||||
(acc, curr) => (curr.score > acc.score ? curr : acc),
|
||||
{ block: undefined, score: 0 },
|
||||
);
|
||||
|
||||
return best.block;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,13 +397,15 @@ export class BlockService extends BaseService<
|
||||
* @param nlpPenaltyFactor - A multiplier applied to scores when the pattern match type is 'entity'.
|
||||
* @returns A numeric score representing how well the block matches the given NLP context.
|
||||
*/
|
||||
calculateBlockScore(
|
||||
async calculateBlockScore(
|
||||
patterns: NlpPattern[],
|
||||
nlp: NLU.ParseEntities,
|
||||
nlpCacheMap: NlpCacheMap,
|
||||
nlpPenaltyFactor: number,
|
||||
): number {
|
||||
): Promise<number> {
|
||||
if (!patterns.length) return 0;
|
||||
|
||||
const nlpCacheMap = await this.entityService.getNlpMap();
|
||||
// @TODO Make nluPenaltyFactor configurable in UI settings
|
||||
const nluPenaltyFactor = 0.95;
|
||||
// Compute individual pattern scores using the cache
|
||||
const patternScores: number[] = patterns.map((pattern) => {
|
||||
const entityData = nlpCacheMap.get(pattern.entity);
|
||||
@ -465,7 +419,7 @@ export class BlockService extends BaseService<
|
||||
matchedEntity,
|
||||
pattern,
|
||||
entityData,
|
||||
nlpPenaltyFactor,
|
||||
nluPenaltyFactor,
|
||||
);
|
||||
});
|
||||
|
||||
@ -473,28 +427,6 @@ export class BlockService extends BaseService<
|
||||
return patternScores.reduce((sum, score) => sum + score, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the names of NLP entities from a given list of blocks.
|
||||
* This method recursively goes through each block, pattern group, and pattern,
|
||||
* filtering for valid NLP patterns and extracting the `entity` field.
|
||||
* The resulting array contains the names of all the NLP entities found across all patterns.
|
||||
*
|
||||
* @param blocks - An array of `BlockFull` objects containing patterns.
|
||||
* @returns An array of NLP entity names as strings.
|
||||
*/
|
||||
private extractNlpEntityNames(blocks: BlockFull[]): string[] {
|
||||
return blocks.flatMap((block) =>
|
||||
block.patterns.flatMap((patternGroup) => {
|
||||
if (Array.isArray(patternGroup)) {
|
||||
return patternGroup.flatMap((pattern) =>
|
||||
isNlpPattern(pattern) ? [pattern.entity] : [],
|
||||
);
|
||||
}
|
||||
return []; // Skip non-array patternGroups
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given `ParseEntity` from the NLP model matches the specified pattern
|
||||
* and if its value exists within the values provided in the cache for the specified entity.
|
||||
|
@ -239,7 +239,7 @@ describe('nlpEntityService', () => {
|
||||
id: '1',
|
||||
weight: 1,
|
||||
};
|
||||
const firstMockLookup = {
|
||||
const firstMockEntity = {
|
||||
name: 'intent',
|
||||
...firstMockValues,
|
||||
values: [{ value: 'buy' }, { value: 'sell' }],
|
||||
@ -248,42 +248,31 @@ describe('nlpEntityService', () => {
|
||||
id: '2',
|
||||
weight: 5,
|
||||
};
|
||||
const secondMockLook = {
|
||||
const secondMockEntity = {
|
||||
name: 'subject',
|
||||
...secondMockValues,
|
||||
values: [{ value: 'product' }],
|
||||
} as unknown as Partial<NlpEntityFull>;
|
||||
const mockLookups = [firstMockLookup, secondMockLook];
|
||||
|
||||
const entityNames = ['intent', 'subject'];
|
||||
const mockEntities = [firstMockEntity, secondMockEntity];
|
||||
|
||||
// Mock findAndPopulate
|
||||
jest
|
||||
.spyOn(nlpEntityService, 'findAndPopulate')
|
||||
.mockResolvedValue(mockLookups as unknown as NlpEntityFull[]);
|
||||
.spyOn(nlpEntityService, 'findAllAndPopulate')
|
||||
.mockResolvedValue(mockEntities as unknown as NlpEntityFull[]);
|
||||
|
||||
// Act
|
||||
const result = await nlpEntityService.getNlpMap(entityNames);
|
||||
const result = await nlpEntityService.getNlpMap();
|
||||
|
||||
expect(result).toBeInstanceOf(Map);
|
||||
expect(result.size).toBe(2);
|
||||
expect(result.get('intent')).toEqual({
|
||||
...firstMockValues,
|
||||
values: ['buy', 'sell'],
|
||||
name: 'intent',
|
||||
...firstMockEntity,
|
||||
});
|
||||
expect(result.get('subject')).toEqual({
|
||||
...secondMockValues,
|
||||
values: ['product'],
|
||||
name: 'subject',
|
||||
...secondMockEntity,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty map if no lookups are found', async () => {
|
||||
jest.spyOn(nlpEntityService, 'findAndPopulate').mockResolvedValue([]);
|
||||
|
||||
const result = await nlpEntityService.getNlpMap(['nonexistent']);
|
||||
|
||||
expect(result).toBeInstanceOf(Map);
|
||||
expect(result.size).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -163,17 +163,11 @@ export class NlpEntityService extends BaseService<
|
||||
* @returns A Promise that resolves to a map of entity name to its corresponding lookup metadata.
|
||||
*/
|
||||
@Cacheable(NLP_MAP_CACHE_KEY)
|
||||
async getNlpMap(entityNames: string[]): Promise<NlpCacheMap> {
|
||||
const lookups = await this.findAndPopulate({ name: { $in: entityNames } });
|
||||
const map: NlpCacheMap = new Map();
|
||||
for (const lookup of lookups) {
|
||||
map.set(lookup.name, {
|
||||
id: lookup.id,
|
||||
weight: lookup.weight,
|
||||
values: lookup.values?.map((v) => v.value) ?? [],
|
||||
});
|
||||
}
|
||||
|
||||
return map;
|
||||
async getNlpMap(): Promise<NlpCacheMap> {
|
||||
const entities = await this.findAllAndPopulate();
|
||||
return entities.reduce((acc, curr) => {
|
||||
acc.set(curr.name, curr);
|
||||
return acc;
|
||||
}, new Map());
|
||||
}
|
||||
}
|
||||
|
@ -291,22 +291,22 @@ export const mockNlpBlock: BlockFull = {
|
||||
'Hello',
|
||||
'/we*lcome/',
|
||||
{ label: 'Mock Nlp', value: 'MOCK_NLP' },
|
||||
|
||||
mockNlpPatternsSetOne,
|
||||
[
|
||||
...mockNlpPatternsSetOne,
|
||||
[
|
||||
{
|
||||
entity: 'intent',
|
||||
match: 'value',
|
||||
value: 'greeting',
|
||||
},
|
||||
{
|
||||
entity: 'firstname',
|
||||
match: 'value',
|
||||
value: 'doe',
|
||||
},
|
||||
],
|
||||
{
|
||||
entity: 'intent',
|
||||
match: 'value',
|
||||
value: 'greeting',
|
||||
},
|
||||
{
|
||||
entity: 'firstname',
|
||||
match: 'value',
|
||||
value: 'doe',
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
trigger_labels: customerLabelsMock,
|
||||
message: ['Good to see you again '],
|
||||
} as unknown as BlockFull;
|
||||
@ -318,12 +318,49 @@ export const mockModifiedNlpBlock: BlockFull = {
|
||||
'Hello',
|
||||
'/we*lcome/',
|
||||
{ label: 'Modified Mock Nlp', value: 'MODIFIED_MOCK_NLP' },
|
||||
[...mockNlpPatternsSetThree],
|
||||
mockNlpPatternsSetThree,
|
||||
],
|
||||
trigger_labels: customerLabelsMock,
|
||||
message: ['Hello there'],
|
||||
} as unknown as BlockFull;
|
||||
|
||||
export const mockModifiedNlpBlockOne: BlockFull = {
|
||||
...baseBlockInstance,
|
||||
name: 'Modified Mock Nlp One',
|
||||
patterns: [
|
||||
'Hello',
|
||||
'/we*lcome/',
|
||||
{ label: 'Modified Mock Nlp One', value: 'MODIFIED_MOCK_NLP_ONE' },
|
||||
mockNlpPatternsSetTwo,
|
||||
[
|
||||
{
|
||||
entity: 'firstname',
|
||||
match: 'entity',
|
||||
},
|
||||
],
|
||||
],
|
||||
trigger_labels: customerLabelsMock,
|
||||
message: ['Hello Sir'],
|
||||
} as unknown as BlockFull;
|
||||
|
||||
export const mockModifiedNlpBlockTwo: BlockFull = {
|
||||
...baseBlockInstance,
|
||||
name: 'Modified Mock Nlp Two',
|
||||
patterns: [
|
||||
'Hello',
|
||||
'/we*lcome/',
|
||||
{ label: 'Modified Mock Nlp Two', value: 'MODIFIED_MOCK_NLP_TWO' },
|
||||
[
|
||||
{
|
||||
entity: 'firstname',
|
||||
match: 'entity',
|
||||
},
|
||||
],
|
||||
mockNlpPatternsSetThree,
|
||||
],
|
||||
trigger_labels: customerLabelsMock,
|
||||
message: ['Hello Madam'],
|
||||
} as unknown as BlockFull;
|
||||
const patternsProduct: Pattern[] = [
|
||||
'produit',
|
||||
[
|
||||
|
Loading…
Reference in New Issue
Block a user