import { removeInvestigationObjectCoordinates } from "@helpers/investigation";
import { ContradictionDetectorService } from "@services/contradictionDetector.service";
import { InvestigationBuilder } from "@services/investigation.builder";
import { getLogger } from "@utils/asyncLocalStorage";
import _ from "lodash";
/**
* Contradiction Processing Service
* @category Services
*/
export class ContradictionProcessingService {
/**
* Contradiction Detector Service instance
* @category Services
*/
detectionService;
/**
* Constructor for Contradiction Processing Service
* @category Services
*/
constructor() {
this.detectionService = new ContradictionDetectorService();
}
/**
* Processes contradictions in an investigation and returns update fields if contradictions are detected.
* @category Services
* @param {IInvestigation} investigation - The investigation to process.
* @returns {Promise<object | null>} - An object with updated fields if contradictions are detected, or `null` otherwise.
*/
async processContradictions(investigation) {
const logger = getLogger();
try {
logger.info({ investigationId: investigation._id }, "Processing contradictions");
// Convert investigation to assistant format
const transformedInvestigation = removeInvestigationObjectCoordinates(investigation);
// Detect contradictions
const contradictionDetectionResponse = await this.detectionService.detectContradiction({
...transformedInvestigation,
});
if (contradictionDetectionResponse.detectedContradiction?.length || 0 > 0) {
contradictionDetectionResponse.detectedContradiction
?.map((value, index) => ({ value, index }))
.reverse()
.forEach((detectedContradiction) => {
if (_.get(investigation, `${detectedContradiction.value.fieldName}.value`) ===
_.get(investigation, `${detectedContradiction.value.fieldName}.aiGeneratedValue`)) {
contradictionDetectionResponse.detectedContradiction?.splice(detectedContradiction.index, 1);
}
});
}
if (contradictionDetectionResponse.detectedContradiction?.length === 0) {
contradictionDetectionResponse.isContradictionDetected = false;
}
// If contradictions are detected, build update fields
logger.info({
investigationId: investigation._id,
contradictionsCount: contradictionDetectionResponse.detectedContradiction?.length,
}, "Contradictions detected");
const updateFields = InvestigationBuilder.buildUpdateContradiction(contradictionDetectionResponse, investigation);
return updateFields;
}
catch (error) {
logger.error({ error, investigationId: investigation._id }, "Failed to process contradictions");
throw error;
}
}
/**
* Processes contradictions in an investigation and applies updates if needed.
* @category Services
* @param {IInvestigation} investigation - The investigation to process.
* @param {Function} updateMethod - The method used to update the investigation.
* @returns {Promise<IInvestigation>} - The investigation after updates have been applied.
*/
async processAndApplyContradictions(investigation, updateMethod) {
const logger = getLogger();
try {
const updateFields = await this.processContradictions(investigation);
if (updateFields) {
logger.info({ investigationId: investigation._id }, "Applying contradiction updates");
const result = await updateMethod(updateFields);
return result.updatedInvestigation;
}
return investigation;
}
catch (error) {
logger.error({ error, investigationId: investigation._id }, "Failed to apply contradiction updates");
throw error;
}
}
}
Source