Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:AgrI-Mitra/bff
Browse files Browse the repository at this point in the history
  • Loading branch information
Amruth-Vamshi committed Mar 4, 2024
2 parents 45ee7e1 + 78c94c3 commit bebca87
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 44 deletions.
2 changes: 2 additions & 0 deletions prisma/migrations/20240220044932_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- DropIndex
DROP INDEX "conversation_userId_flowId_key";
3 changes: 1 addition & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ datasource db {
}

model conversation {
id String @default(uuid()) @db.Uuid
id String @db.Uuid
createdAt DateTime @default(now()) @db.Timestamptz(3)
updatedAt DateTime @updatedAt
userId String @db.Uuid
Expand All @@ -22,7 +22,6 @@ model conversation {
flowId String
feedback feedback?
@@unique([id])
@@unique([userId,flowId])
}

model User {
Expand Down
69 changes: 47 additions & 22 deletions src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,21 @@ export class AppController {
let startTime = Date.now()
//get userId from headers
const userId = headers["user-id"]
const sessionId = headers["session-id"]
console.log("userId =",userId)
console.log("sessionId =", sessionId)
if(!userId){
return {
"text":"",
"error": "'user-id' should not be empty"
}
}
if(!sessionId) {
return {
"text": "",
"error": "'session-id' should not be empty"
}
}
let messageType = 'intermediate_response'
//setup loggers
let verboseLogger = this.logger.logWithCustomFields({
Expand Down Expand Up @@ -152,23 +160,49 @@ export class AppController {
}
})
}
let conversation = await this.conversationService.getConversationState(
userId,
configid
)

//input setup
let prompt: Prompt = {
input: promptDto
}
let userInput = promptDto.text;
let type = "text"

let defaultContext = {
sessionId,
userId,
userQuestion:'',
query: '',
queryType: '',
response: '',
userAadhaarNumber: user.identifier && configid=='3' ? user.identifier : '',
otp: '',
error: '',
currentState: "getUserQuestion",
type: '',
inputType: type,
inputLanguage: prompt.inputLanguage,
lastAadhaarDigits:'',
state:'onGoing',
isOTPVerified: false
}

let conversation = await this.conversationService.getConversationState(
sessionId,
userId,
defaultContext,
configid
)

console.log("fetched conversation: ", conversation)
//handle text and audio
if(promptDto.text){
type = "Text"
let detectLanguageStartTime = Date.now();
if(/^\d+$/.test(userInput)){
prompt.inputLanguage = Language.en
} else {
console.log("IN ELSE....")
try {
let response = await this.aiToolsService.detectLanguage(userInput)
prompt.inputLanguage = response["language"] as Language
Expand Down Expand Up @@ -207,12 +241,14 @@ export class AppController {
tags: ['bot','detect_language','error']
})
}
console.log("LANGUAGE DETECTED...")
//@ts-ignore
if(prompt.inputLanguage == 'unk'){
prompt.inputLanguage = prompt.input.inputLanguage as Language
}
// verboseLogger("Detected Language =", prompt.inputLanguage)
}
console.log("TELEMETRYYYYY")
await this.telemetryService.capture({
eventName: "Detect language",
eventType: "DETECT_LANGUAGE",
Expand Down Expand Up @@ -342,6 +378,8 @@ export class AppController {
}
}

conversation.inputType = type;
console.log("CP 1...")
//get flow
let botFlowMachine;
switch(configid){
Expand All @@ -358,23 +396,7 @@ export class AppController {
botFlowMachine = this.promptService.getXstateMachine("botFlowMachine3")
}

let defaultContext = {
userId,
userQuestion:'',
query: '',
queryType: '',
response: '',
userAadhaarNumber: user.identifier && configid=='3' ? user.identifier : '',
otp: '',
error: '',
currentState: "getUserQuestion",
type: '',
inputType: type,
inputLanguage: prompt.inputLanguage,
lastAadhaarDigits:'',
state:'onGoing',
isOTPVerified: false
}


let botFlowService = interpret(botFlowMachine.withContext(conversation || defaultContext)).start();
// verboseLogger("current state when API hit =", botFlowService.state.context.currentState)
Expand All @@ -393,6 +415,7 @@ export class AppController {
}
})
}else {
console.log("creating a new message in Message table...")
await this.prismaService.message.create({
data:{
text: type=="Text"?promptDto.text:null,
Expand Down Expand Up @@ -487,6 +510,7 @@ export class AppController {
return res
} else {
//translate to english
console.log("Translating to English...")
let translateStartTime = Date.now();
if(userInput == 'resend OTP'){
this.monitoringService.incrementResentOTPCount()
Expand Down Expand Up @@ -1083,8 +1107,9 @@ export class AppController {
result['audio'] = {text: "",error: error.message}
}
}

console.log("Saving conversation..")
conversation = await this.conversationService.saveConversation(
sessionId,
userId,
botFlowService.getSnapshot().context,
botFlowService.state.context.state,
Expand Down
7 changes: 4 additions & 3 deletions src/modules/aiTools/ai-tools.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class AiToolsService {
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
) {}
async detectLanguage(text: string): Promise<any> {
console.log("DETECTING LANGUAGE....")
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

Expand Down Expand Up @@ -260,18 +261,18 @@ export class AiToolsService {
}
}

async getResponseViaWadhwani(text: string) {
async getResponseViaWadhwani(sessionId: string, userId: string, text: string) {
try{
var myHeaders = new Headers();
myHeaders.append("accept", "application/json");
myHeaders.append("X-API-Key", this.configService.get("WADHWANI_API_KEY"));
let response: any = await fetch(`${this.configService.get("WADHWANI_BASE_URL")}/get_bot_response?query=${text}`, {
let response: any = await fetch(`${this.configService.get("WADHWANI_BASE_URL")}/get_bot_response?query=${text}&user_id=${userId}&session_id=${sessionId}`, {
headers: myHeaders,
"method": "GET",
"mode": "cors",
"credentials": "omit"
});
response = (await response.text()).replace(/^\"|\"$/g, '')
response = await response.json()
return response
} catch(error){
console.log(error)
Expand Down
53 changes: 47 additions & 6 deletions src/modules/conversation/conversation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ export class ConversationService {
}

async saveConversation(
sessionId: string,
userId: string,
context: any,
state: string,
flowId: string
): Promise<any> {
return await this.prisma.conversation.upsert({
where: { userId_flowId: {userId, flowId} },
where: { id: sessionId },
create: {
id: sessionId,
userId,
context,
state,
Expand All @@ -34,20 +36,59 @@ export class ConversationService {
}

async getConversationState(
sessionId: string,
userId: string,
flowId: string
defaultContext: any,
flowId: string,
): Promise<any | null> {
const conversation: any = await this.prisma.conversation.findFirst({
let conversation: any = await this.prisma.conversation.findFirst({
where: {
userId,
flowId,
state: 'onGoing'
id: sessionId
},
});

if(!conversation) {
conversation = await this.prisma.conversation.create({
data: {
id: sessionId,
userId,
context: defaultContext,
flowId,
state: 'onGoing'
}
})
}

if(conversation.state == "Done") {
conversation = await this.prisma.conversation.update({
where: {
id: sessionId
},
data: {
context: defaultContext,
state: "onGoing"
}
})

conversation = await this.prisma.conversation.findFirst({
where: {
id: sessionId
}
})
}

return conversation?.context ? {...conversation.context, id:conversation.id} : null;
}

async getConversationById(sessionId: string): Promise<any | null> {
const conversation: any = await this.prisma.conversation.findFirst({
where: {
id: sessionId
}
});
return conversation?.id ? conversation : null;
}

async createOrUpdateFeedback(
feedback: any
): Promise<feedback> {
Expand Down
4 changes: 2 additions & 2 deletions src/xstate/prompt/prompt.gaurds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export const promptGuards = {

ifOTPHasBeenVerified: (context,_) => context.isOTPVerified,

ifInvalidClassifier: (_,event) => event.data == "invalid",
ifInvalidClassifier: (_,event) => event.data.class == "invalid",

ifConvoStarterOrEnder: (_,event) => event.data == "convo"
ifConvoStarterOrEnder: (_,event) => event.data.class == "convo"

}
6 changes: 4 additions & 2 deletions src/xstate/prompt/prompt.machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,19 +878,21 @@ export const botFlowMachine3:any =
onDone: [
{
cond: "ifConvoStarterOrEnder",
target: "wadhwaniClassifier",
target: "endFlow",
actions: [
assign({
queryType: (_,event) => event.data,
response: (_,event) => event.data.response,
isWadhwaniResponse: "true"
})
]
},
{
cond: "ifInvalidClassifier",
target: "wadhwaniClassifier",
target: "endFlow",
actions: [
assign({
response: (_,event) => event.data.response,
isWadhwaniResponse: "true"
})
]
Expand Down
32 changes: 25 additions & 7 deletions src/xstate/prompt/prompt.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,29 @@ export class PromptServices {
}

async questionClassifier (context) {
console.log("IN questionclassifier")
try{
let response: any = await this.aiToolsService.textClassification(context.query)
let response: any = await this.aiToolsService.getResponseViaWadhwani(context.sessionId, context.userId, context.query)
if (response.error) throw new Error(`${response.error}, please try again.`)
if (response == `"Invalid"`) return "convo"
if (response == `"convo_starter"`) return "convo"
if (response == `"convo_ender"`) return "convo"
if (response == `"Installment Not Received"`) return "payment"
// {
// "user_id": "19877818",
// "session_id": "123456",
// "query": "Installment not received",
// "query_intent": "Installment not received",
// "language": "English",
// "response": "Dear Beneficiary, You can check your status using Know Your Status (KYS) module at https://pmkisan.gov.in/BeneficiaryStatus_New.aspx. \nIf you are not satisfied with the status, please contact the PM Kisan officer Shri ABC on 9809898989 or you can also visit the Officer at PM Kisan Officer, 193310 village, 868 block, 965 sub-district, 123 district, 9, Pincode: . \nFor further assistant, please contact on the PM Kisan Samman Nidhi helpline number: 155261 / 011-24300606. The helpline is available on all working days from 9:30 AM to 6:00 PM."
// }
let intent;
if (response.query_intent == "Invalid") intent = "convo"
if (response.query_intent == "convo_starter") intent = "convo"
if (response.query_intent == "convo_ender") intent = "convo"
if (response.query_intent == "Installment Not Received") intent = "payment"
else {
return "invalid"
intent = "invalid"
}
return {
class: intent,
response: response.response
}
} catch (error){
return Promise.reject(error)
Expand All @@ -55,6 +69,7 @@ export class PromptServices {
}

async validateAadhaarNumber (context, event) {
console.log("validate aadhar")
try{
const userIdentifier = `${context.userAadhaarNumber}${context.lastAadhaarDigits}`;
let res;
Expand Down Expand Up @@ -88,6 +103,7 @@ export class PromptServices {
}

async validateOTP (context, event) {
console.log("Validate OTP")
const userIdentifier = `${context.userAadhaarNumber}${context.lastAadhaarDigits}`;
const otp = context.otp;
let res;
Expand All @@ -111,6 +127,7 @@ export class PromptServices {
}

async fetchUserData (context, event) {
console.log("Fetch user data");
const userIdentifier = `${context.userAadhaarNumber}${context.lastAadhaarDigits}`;
let res;
let type='Mobile'
Expand Down Expand Up @@ -197,8 +214,9 @@ export class PromptServices {
}

async wadhwaniClassifier (context) {
console.log("Wadhwani Classifierrr")
try{
let response: any = await this.aiToolsService.getResponseViaWadhwani(context.query)
let response: any = await this.aiToolsService.getResponseViaWadhwani(context.sessionId, context.userId,context.query)
if (response.error) throw new Error(`${response.error}, please try again.`)
return response;
} catch (error){
Expand Down

0 comments on commit bebca87

Please sign in to comment.