112211
<p>/* eslint-disable */<br />
import { Inject, Injectable, Headers, InternalServerErrorException, BadRequestException } from '@nestjs/common';<br />
import { AxiosUtil, LOGGER, LoggerUtil } from '@cvsdigital_sdk/nest-graphql-common';<br />
import { ConfigService } from '@nestjs/config';<br />
import CacheUtil from './utils/cache.util';</p>
<p>import MasterIntentClassifierResponse from './model/masterintent.model';<br />
import IntentClassEnum from './model/intentClass.enum';<br />
import { IntentRule, IntentRules } from './model/intent-rules.interface';<br />
import { MatchedIntentResponse } from './model/matched-intent-response.model';<br />
import DigitalIVRSessionsEntity from './entity/DigitalIVRSessions.entity';<br />
import { InjectRepository } from '@nestjs/typeorm';<br />
import { Repository } from 'typeorm';<br />
import PrescriberAddress from './masterintent.repository';</p>
<p>import IntentExperienceService from './intent.experience.service';<br />
import { performance } from 'perf_hooks';</p>
<p>@Injectable()<br />
export default class MasterIntentService {<br />
private configPrefix: string;<br />
constructor(<br />
private axiosUtil: AxiosUtil,<br />
private readonly configService: ConfigService,<br />
private readonly cacheUtil: CacheUtil,<br />
private readonly experienceService: IntentExperienceService,<br />
@InjectRepository(DigitalIVRSessionsEntity)<br />
private digitalIVRSessionsEntity: Repository<DigitalIVRSessionsEntity>,<br />
@Inject(LOGGER) private readonly logger: LoggerUtil,<br />
) {}</p>
<p> public setConfigPrefix(channel: string | string[]): void {<br />
let prefix: string;</p>
<p> if (Array.isArray(channel)) {<br />
prefix = channel[0];<br />
} else {<br />
prefix = channel;<br />
}</p>
<p> if (prefix !== 'X42_IVR' && prefix !== 'X42_CHAT') {<br />
prefix = 'X42_IVR';<br />
}<br />
this.configPrefix = prefix;<br />
}</p>
<p> /**<br />
* Get Master Intent<br />
* @param userText<br />
* @param channel<br />
* @param id<br />
* @param idType<br />
*/<br />
public async getMasterIntent(userText: string, id?: string, idType?: string, store?: string): Promise<any> {<br />
const startTime = performance.now();<br />
const masterIntentResponse: MasterIntentClassifierResponse = new MasterIntentClassifierResponse();<br />
masterIntentResponse.statusFlags = {<br />
expeditedPrescriptionEligibleCount: -1,<br />
prescriptionEligibleCount: -1,<br />
cancelPrescriptionEligibleCount: -1,<br />
refillablePrescriptionEligibleCount: -1,<br />
transferPrescriptionEligibleCount: -1,<br />
prescriptionStatus: [],<br />
};</p>
<p> // Classify intent and skip words in parallel<br />
const mlResponsePromise = this.classifyIntent(userText);<br />
const skipWordsPromise = this.configService.get<string[]>(`skipWords`) || [];<br />
const cacheLogicPromise = id && idType ? this.handleCacheLogic(masterIntentResponse, id, idType) : Promise.resolve();<br />
const userQueryCache = this.getUserQueryCache(userText, masterIntentResponse);</p>
<p> const [mlResponse, skipWords, cacheLogicResponse, userCacheResponse] = await Promise.all([<br />
mlResponsePromise,<br />
skipWordsPromise,<br />
cacheLogicPromise,<br />
userQueryCache,<br />
]);</p>
<p> // Process high-level intent and check if it should be skipped<br />
const highLevelIntent = mlResponse?.intents.length ? mlResponse.intents[0].toLowerCase().trim() : 'unknown';<br />
const isSkip = skipWords.some((word) => highLevelIntent.toLowerCase().includes(word.toLowerCase()));</p>
<p> let intentResp: string[] | undefined;</p>
<p> // Get Intent AI data if not skipping and cache is not available<br />
if (highLevelIntent !== 'unknown' && !isSkip && !userCacheResponse) {<br />
const intentAIDataPromise = this.getIntentAIData(userText, highLevelIntent);<br />
const response = await intentAIDataPromise;<br />
intentResp = response?.chat_response.split(',');<br />
masterIntentResponse.subIntent = intentResp.map((i: string) => i.toLowerCase().trim());<br />
} else {<br />
masterIntentResponse.subIntent = userCacheResponse ? [userCacheResponse] : [highLevelIntent];<br />
}</p>
<p> masterIntentResponse.userText = userText;</p>
<p> // Filter out 'help' from subIntents if necessary<br />
const valueToRemove = 'help';<br />
masterIntentResponse.subIntent =<br />
masterIntentResponse.subIntent.length > 1<br />
? masterIntentResponse.subIntent.filter((item) => item !== valueToRemove)<br />
: masterIntentResponse.subIntent;</p>
<p> await cacheLogicPromise;</p>
<p> // Handle intent matching<br />
let matchedIntent: MatchedIntentResponse = await this.matchIntent(masterIntentResponse.subIntent);</p>
<p> if (masterIntentResponse.subIntent.includes('unknown')) {<br />
masterIntentResponse.intent = String(IntentClassEnum.INTENT_UNKNOWN);<br />
} else if (matchedIntent.matchedAttributes.mainIntent === 'multiintent') {<br />
matchedIntent = await this.matchExceptionIntent(masterIntentResponse.subIntent);<br />
}</p>
<p> masterIntentResponse.intent = matchedIntent.matchedAttributes.mainIntent;<br />
masterIntentResponse.fillerText = matchedIntent.partialFiller;<br />
masterIntentResponse.promptId = matchedIntent.matchedAttributes.promptID?.trim() || '-1';<br />
masterIntentResponse.templateId = matchedIntent.matchedAttributes.dataTemplate?.trim() || '-1';<br />
masterIntentResponse.ruleNo = matchedIntent.matchedAttributes.ruleNo?.trim() || '-1';<br />
masterIntentResponse.seqNo = matchedIntent.matchedAttributes.seqNo;</p>
<p> // Additional check for patient interaction<br />
let patientInteractedRecently = false;<br />
masterIntentResponse.statusFlags.patientInteractedRecently = patientInteractedRecently;<br />
if (masterIntentResponse.intent === 'live_pharmacist' && id) {<br />
patientInteractedRecently = await this.hasRecentEntry(id);<br />
masterIntentResponse.statusFlags.patientInteractedRecently = patientInteractedRecently;<br />
this.logger.addFunctionalTags(<br />
'masterIntentResponse.patientInteractedRecently',<br />
`${patientInteractedRecently}`,<br />
);<br />
}</p>
<p> // Call classifyIntentForPartialFiller and set fillerText<br />
const partialFillerResponse = await this.classifyIntentForPartialFiller(userText, highLevelIntent);<br />
masterIntentResponse.fillerText = partialFillerResponse?.text || '';</p>
<p> // Log response and performance<br />
this.logger.addFunctionalTags('masterIntentResponse.intent', `${masterIntentResponse.intent}`);<br />
this.logger.addFunctionalTags('masterIntentResponse.subIntent', `${masterIntentResponse.subIntent}`);<br />
this.logger.addFunctionalTags('masterIntentResponse.fillerText', `${masterIntentResponse.fillerText}`);<br />
this.logger.addFunctionalTags('masterIntentResponse.promptId', `${masterIntentResponse.promptId}`);<br />
this.logger.addFunctionalTags('masterIntentResponse.templateId', `${masterIntentResponse.templateId}`);<br />
this.logger.addFunctionalTags('masterIntentResponse.ruleId', `${matchedIntent.matchedAttributes.ruleNo}`);<br />
this.logger.addFunctionalTags('masterIntentResponse.seqNo', `${matchedIntent.matchedAttributes.seqNo}`);<br />
this.logger.addFunctionalTags('masterIntentResponse', `${JSON.stringify(masterIntentResponse)}`);<br />
const endTime = performance.now();<br />
const duration = endTime - startTime;<br />
this.logger.addFunctionalTags('MasterIntentServiceTimeTaken', `${duration}ms`);</p>
<p> return masterIntentResponse;<br />
}</p>
<p> /**<br />
* Classify Intent for Partial Filler<br />
* @param userText<br />
* @param highLevelIntent<br />
* @returns Partial filler text response<br />
*/<br />
private async classifyIntentForPartialFiller(userText: string, highLevelIntent: string): Promise<any> {<br />
const classifyIntentReq: any = {<br />
query: userText,<br />
intent: highLevelIntent,<br />
};<br />
this.logger.addFunctionalTags('classifyIntentForPartialFillerRequest', classifyIntentReq);</p>
<p> // Extract the client name directly without including the configPrefix<br />
const clientName = `${this.configPrefix}.ClassifyIntentForPartialFiller`;</p>
<p> // Use the configPrefix to correctly fetch the URI<br />
const uri = this.configService.get<string>(`client.${clientName}.uri`);<br />
this.logger.addFunctionalTags('configUriForPartialFiller', uri);</p>
<p> const startTime = performance.now();</p>
<p> const classifyIntentForPartialFillerResponse: any = await this.axiosUtil.getInstance(clientName).post(uri, classifyIntentReq);<br />
const endTime = performance.now();<br />
const duration = endTime - startTime;<br />
this.logger.addFunctionalTags('classifyIntentForPartialFillerTimeTaken', `${duration}ms`);</p>
<p> this.logger.addFunctionalTags('classifyIntentForPartialFillerResponse', classifyIntentForPartialFillerResponse);<br />
return classifyIntentForPartialFillerResponse;<br />
}</p>
<p> // Other existing methods ...<br />
}<br />
</p>