feat: add nlp cache map type

This commit is contained in:
Mohamed Marrouchi
2025-04-08 10:53:20 +01:00
committed by MohamedAliBouhaouala
parent 01a97ccc46
commit eeb9142c45
3 changed files with 24 additions and 29 deletions

View File

@@ -37,6 +37,7 @@ 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';
@@ -432,20 +433,17 @@ describe('BlockService', () => {
describe('calculateBlockScore', () => {
it('should calculate the correct NLP score for a block', async () => {
const entityCache = new Map<
string,
{ id: string; weight: number; values: string[] }
>();
const nlpCacheMap: NlpCacheMap = new Map();
const score = await blockService.calculateBlockScore(
mockNlpPatternsSetOne,
mockNlpEntitiesSetOne,
entityCache,
nlpCacheMap,
);
const score2 = await blockService.calculateBlockScore(
mockNlpPatternsSetTwo,
mockNlpEntitiesSetOne,
entityCache,
nlpCacheMap,
);
expect(score).toBeGreaterThan(0);
@@ -453,23 +451,17 @@ describe('BlockService', () => {
});
it('should return 0 if no matching entities are found', async () => {
const entityCache = new Map<
string,
{ id: string; weight: number; values: string[] }
>();
const nlpCacheMap: NlpCacheMap = new Map();
const score = await blockService.calculateBlockScore(
mockNlpPatternsSetTwo,
mockNlpEntitiesSetOne,
entityCache,
nlpCacheMap,
);
expect(score).toBe(0); // No matching entity, so score should be 0
});
it('should correctly use entity cache to avoid redundant database calls', async () => {
const entityCache = new Map<
string,
{ id: string; weight: number; values: string[] }
>();
const nlpCacheMap: NlpCacheMap = new Map();
// Create spies on the services
const entityServiceSpy = jest.spyOn(mockNlpEntityService, 'findOne');
@@ -479,9 +471,9 @@ describe('BlockService', () => {
await blockService.calculateBlockScore(
mockNlpPatternsSetOne,
mockNlpEntitiesSetOne,
entityCache,
nlpCacheMap,
);
const cacheSizeBefore = entityCache.size;
const cacheSizeBefore = nlpCacheMap.size;
const entityCallsBefore = entityServiceSpy.mock.calls.length;
const valueCallsBefore = valueServiceSpy.mock.calls.length;
@@ -489,9 +481,9 @@ describe('BlockService', () => {
await blockService.calculateBlockScore(
mockNlpPatternsSetOne,
mockNlpEntitiesSetOne,
entityCache,
nlpCacheMap,
);
const cacheSizeAfter = entityCache.size;
const cacheSizeAfter = nlpCacheMap.size;
const entityCallsAfter = entityServiceSpy.mock.calls.length;
const valueCallsAfter = valueServiceSpy.mock.calls.length;

View File

@@ -16,6 +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 } 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';
@@ -391,10 +392,7 @@ export class BlockService extends BaseService<
let bestBlock: Block | BlockFull | undefined;
let highestScore = 0;
const entityCache = new Map<
string,
{ id: string; weight: number; values: string[] }
>();
const nlpCacheMap: NlpCacheMap = new Map();
// Iterate through all blocks and calculate their NLP score
for (let i = 0; i < blocks.length; i++) {
@@ -405,7 +403,7 @@ export class BlockService extends BaseService<
const nlpScore = await this.calculateBlockScore(
patterns,
nlp,
entityCache,
nlpCacheMap,
);
if (nlpScore > highestScore) {
@@ -427,13 +425,13 @@ export class BlockService extends BaseService<
*
* @param patterns - The NLP patterns matched for the block
* @param nlp - The parsed NLP entities
* @param entityCache - A cache for storing previously fetched entity data to avoid redundant DB calls
* @param nlpCacheMap - A cache for storing previously fetched entity data to avoid redundant DB calls
* @returns The calculated NLP score for the block
*/
async calculateBlockScore(
patterns: NlpPattern[],
nlp: NLU.ParseEntities,
entityCache: Map<string, { id: string; weight: number; values: string[] }>,
nlpCacheMap: NlpCacheMap,
): Promise<number> {
let nlpScore = 0;
@@ -442,7 +440,7 @@ export class BlockService extends BaseService<
const entityName = pattern.entity;
// Retrieve entity data from cache or database if not cached
let entityData = entityCache.get(entityName);
let entityData = nlpCacheMap.get(entityName);
if (!entityData) {
const entityLookup = await this.entityService.findOne(
{ name: entityName },
@@ -464,7 +462,7 @@ export class BlockService extends BaseService<
weight: entityLookup.weight,
values,
};
entityCache.set(entityName, entityData);
nlpCacheMap.set(entityName, entityData);
}
// Check if the NLP entity matches with the cached data

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
@@ -25,3 +25,8 @@ export enum NlpSampleState {
test = 'test',
inbox = 'inbox',
}
export type NlpCacheMap = Map<
string,
{ id: string; weight: number; values: string[] }
>;