mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
feat: implement nlp based blocks prioritization strategy
feat: add weight to nlp entity schema and readapt feat: remove commented obsolete code feat: restore settings feat: apply feedback fix: re-adapt unit tests feat: priority scoring re-calculation & enabling weight modification in builtin nlp entities fix: remove obsolete code feat: refine unit tests, apply mr coderabbit suggestions fix: minor refactoring feat: add nlp cache map type feat: refine builtin nlp entities weight updates feat: add more test cases and refine edge case handling feat: add weight validation in UI fix: apply feedback feat: add a penalty factor & fix unit tests feat: add documentation fix: correct syntax fix: remove stale log statement fix: enforce nlp entity weight restrictions fix: correct typo in docs fix: typos in docs fix: fix formatting for function comment fix: restore matchNLP function previous code fix: remove blank line, make updateOne asynchronous fix: add AND operator in docs fix: handle dependency injection in chat module feat: refactor to use findAndPopulate in block score calculation feat: refine caching mechanisms feat: add typing and enforce safety checks fix: remove typo fix: remove async from block score calculation fix: remove typo fix: correct linting fix: refine nlp pattern type check fix: decompose code into helper utils, add nlp entity dto validation, remove type casting fix: minor refactoring feat: refactor current implementation
This commit is contained in:
committed by
Mohamed Marrouchi
parent
0db40680dc
commit
bab2e3082f
@@ -6,6 +6,7 @@
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import {
|
||||
BadRequestException,
|
||||
MethodNotAllowedException,
|
||||
@@ -67,6 +68,12 @@ describe('NlpEntityController', () => {
|
||||
NlpValueService,
|
||||
NlpSampleEntityRepository,
|
||||
NlpValueRepository,
|
||||
{
|
||||
provide: CACHE_MANAGER,
|
||||
useValue: {
|
||||
del: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
[nlpEntityController, nlpValueService, nlpEntityService] = await getMocks([
|
||||
@@ -109,6 +116,7 @@ describe('NlpEntityController', () => {
|
||||
) as NlpEntityFull['values'],
|
||||
lookups: curr.lookups!,
|
||||
builtin: curr.builtin!,
|
||||
weight: curr.weight!,
|
||||
});
|
||||
return acc;
|
||||
},
|
||||
@@ -163,6 +171,7 @@ describe('NlpEntityController', () => {
|
||||
name: 'sentiment',
|
||||
lookups: ['trait'],
|
||||
builtin: false,
|
||||
weight: 1,
|
||||
};
|
||||
const result = await nlpEntityController.create(sentimentEntity);
|
||||
expect(result).toEqualPayload(sentimentEntity);
|
||||
@@ -214,6 +223,7 @@ describe('NlpEntityController', () => {
|
||||
updatedAt: firstNameEntity!.updatedAt,
|
||||
lookups: firstNameEntity!.lookups,
|
||||
builtin: firstNameEntity!.builtin,
|
||||
weight: firstNameEntity!.weight,
|
||||
};
|
||||
const result = await nlpEntityController.findOne(firstNameEntity!.id, [
|
||||
'values',
|
||||
@@ -238,6 +248,7 @@ describe('NlpEntityController', () => {
|
||||
doc: '',
|
||||
lookups: ['trait'],
|
||||
builtin: false,
|
||||
weight: 1,
|
||||
};
|
||||
const result = await nlpEntityController.updateOne(
|
||||
firstNameEntity!.id,
|
||||
@@ -258,7 +269,7 @@ describe('NlpEntityController', () => {
|
||||
).rejects.toThrow(NotFoundException);
|
||||
});
|
||||
|
||||
it('should throw exception when nlp entity is builtin', async () => {
|
||||
it('should throw an exception if entity is builtin but weight not provided', async () => {
|
||||
const updateNlpEntity: NlpEntityCreateDto = {
|
||||
name: 'updated',
|
||||
doc: '',
|
||||
@@ -269,6 +280,57 @@ describe('NlpEntityController', () => {
|
||||
nlpEntityController.updateOne(buitInEntityId!, updateNlpEntity),
|
||||
).rejects.toThrow(MethodNotAllowedException);
|
||||
});
|
||||
|
||||
it('should update weight if entity is builtin and weight is provided', async () => {
|
||||
const updatedNlpEntity: NlpEntityCreateDto = {
|
||||
name: 'updated',
|
||||
doc: '',
|
||||
lookups: ['trait'],
|
||||
builtin: false,
|
||||
weight: 4,
|
||||
};
|
||||
const findOneSpy = jest.spyOn(nlpEntityService, 'findOne');
|
||||
const updateWeightSpy = jest.spyOn(nlpEntityService, 'updateWeight');
|
||||
|
||||
const result = await nlpEntityController.updateOne(
|
||||
buitInEntityId!,
|
||||
updatedNlpEntity,
|
||||
);
|
||||
|
||||
expect(findOneSpy).toHaveBeenCalledWith(buitInEntityId!);
|
||||
expect(updateWeightSpy).toHaveBeenCalledWith(
|
||||
buitInEntityId!,
|
||||
updatedNlpEntity.weight,
|
||||
);
|
||||
expect(result.weight).toBe(updatedNlpEntity.weight);
|
||||
});
|
||||
|
||||
it('should update only the weight of the builtin entity', async () => {
|
||||
const updatedNlpEntity: NlpEntityCreateDto = {
|
||||
name: 'updated',
|
||||
doc: '',
|
||||
lookups: ['trait'],
|
||||
builtin: false,
|
||||
weight: 4,
|
||||
};
|
||||
const originalEntity: NlpEntity | null = await nlpEntityService.findOne(
|
||||
buitInEntityId!,
|
||||
);
|
||||
|
||||
const result: NlpEntity = await nlpEntityController.updateOne(
|
||||
buitInEntityId!,
|
||||
updatedNlpEntity,
|
||||
);
|
||||
|
||||
// Check weight is updated
|
||||
expect(result.weight).toBe(updatedNlpEntity.weight);
|
||||
|
||||
Object.entries(originalEntity!).forEach(([key, value]) => {
|
||||
if (key !== 'weight' && key !== 'updatedAt') {
|
||||
expect(result[key as keyof typeof result]).toEqual(value);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('deleteMany', () => {
|
||||
it('should delete multiple nlp entities', async () => {
|
||||
|
||||
@@ -157,10 +157,19 @@ export class NlpEntityController extends BaseController<
|
||||
this.logger.warn(`Unable to update NLP Entity by id ${id}`);
|
||||
throw new NotFoundException(`NLP Entity with ID ${id} not found`);
|
||||
}
|
||||
|
||||
if (nlpEntity.builtin) {
|
||||
throw new MethodNotAllowedException(
|
||||
`Cannot update builtin NLP Entity ${nlpEntity.name}`,
|
||||
);
|
||||
// Only allow weight update for builtin entities
|
||||
if (updateNlpEntityDto.weight) {
|
||||
return await this.nlpEntityService.updateWeight(
|
||||
id,
|
||||
updateNlpEntityDto.weight,
|
||||
);
|
||||
} else {
|
||||
throw new MethodNotAllowedException(
|
||||
`Cannot update builtin NLP Entity ${nlpEntity.name} except for weight`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return await this.nlpEntityService.updateOne(id, updateNlpEntityDto);
|
||||
|
||||
@@ -372,6 +372,7 @@ describe('NlpSampleController', () => {
|
||||
lookups: ['trait'],
|
||||
doc: '',
|
||||
builtin: false,
|
||||
weight: 1,
|
||||
};
|
||||
const priceValueEntity = await nlpEntityService.findOne({
|
||||
name: 'intent',
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||
*/
|
||||
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import { BadRequestException, NotFoundException } from '@nestjs/common';
|
||||
import { MongooseModule } from '@nestjs/mongoose';
|
||||
|
||||
@@ -57,6 +58,12 @@ describe('NlpValueController', () => {
|
||||
NlpSampleEntityRepository,
|
||||
NlpEntityService,
|
||||
NlpEntityRepository,
|
||||
{
|
||||
provide: CACHE_MANAGER,
|
||||
useValue: {
|
||||
del: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
[nlpValueController, nlpValueService, nlpEntityService] = await getMocks([
|
||||
|
||||
Reference in New Issue
Block a user