Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update onboarding and confirmation scripts #10

Merged
merged 6 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions src/xyz/didx/ai/AiHandler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,25 @@ object AiHandler {
case ChatState.Onboarding =>
IO(Try {
val result: OnboardingResult = OnboardingHandler.getResponse(input, conversationId, telNo)
scribe.info(
s"Got response from OnboardingHandler::getResponse, for conversationId: $conversationId"
)
val (messageToUser, nextState) = result match {
case OnboardingResult(_, Some(fullName), Some(email), Some(cellphone)) =>
// Results are records. Store in onboardingResults Map, and move to confirmation state
onboardingResults.update(conversationId, result)
scribe.info(
s"Recorded onboarding result for conversationId: $conversationId"
)

onboardingResults.update(conversationId, result) // Store in onboardingResults Map

val response = "Thank you. Please confirm if the following recorded data is correct:\n\n" +
s"Name: ${result.fullName.getOrElse("None")}\n" +
s"Email: ${result.email.getOrElse("None")}\n" +
s"Cellphone: ${result.cellphone.getOrElse("None")}"
val response = ConfirmOnboardingHandler.getConfirmationMessage(result)

(response, ChatState.ConfirmOnboardingResult)
(response, ChatState.ConfirmOnboardingResult) // move to confirmation state

case OnboardingResult(_, _, _, _) => // In case data is not yet fully captured, remain in same state
case OnboardingResult(_, _, _, _) =>
scribe.info(
s"Data is not yet fully captured, remain in same state for conversationId: $conversationId"
)
(result.nextMessageToUser, state)
}
(messageToUser, nextState)
Expand All @@ -56,9 +62,12 @@ object AiHandler {
onboardingResultOpt match
case None => ("Something went wrong retrieving recorded results. Let's try again!", ChatState.Onboarding)
case Some(onboardingResult) =>
val confirmationResult = ConfirmOnboardingHandler.getConfirmation(input, onboardingResult, conversationId)
confirmationResult.confirmed match
case None => (confirmationResult.nextMessageToUser, state)
val confirmationResult = ConfirmOnboardingHandler.getConfirmation(input, conversationId)
confirmationResult.userHasConfirmedOptionalBool match
case None => (
ConfirmOnboardingHandler.getReconfirmationMessage(onboardingResult),
ChatState.ConfirmOnboardingResult
)
case Some(true) => (
"Great, you are now ready to query the available Yoma opportunities! What would you like to do?",
ChatState.QueryingOpportunities
Expand Down
26 changes: 17 additions & 9 deletions src/xyz/didx/ai/handler/ConfirmOnboardingResult.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,16 @@ import xyz.didx.ai.model.OnboardingResult
import xyz.didx.ai.model.AgentScript

object ConfirmOnboardingHandler {
// Define a map from conversationId to JvmPromptBuilder
private val builders: mutable.Map[String, PromptBuilder] = mutable.Map()

def getConfirmation(
input: String,
onboardingResult: OnboardingResult,
conversationId: String
): ConfirmedOnboardingResult = {
scribe.info(
s"Get ConfirmOnboardingResult response for message: $input, for conversationId: $conversationId"
)
// Get the builder for this conversationId, or create a new one if it doesn't exist
val builder = builders.getOrElseUpdate(
conversationId,
AgentScript.createConfirmationBuilder(onboardingResult)
)

// Get the prompt builder for this script
val builder = AgentScript.createConfirmationBuilder()

// Add the user message to the builder
builder.addUserMessage(input)
Expand All @@ -40,4 +34,18 @@ object ConfirmOnboardingHandler {
conversationId = Some(ConversationId(conversationId))
)
}

def getConfirmationMessage(result: OnboardingResult): String =
"Thank you. Please confirm if the following recorded data is correct:\n\n" +
s"Name: ${result.fullName.getOrElse("None")}\n" +
s"Email: ${result.email.getOrElse("None")}\n" +
s"Cellphone: ${result.cellphone.getOrElse("None")}"

def getReconfirmationMessage(result: OnboardingResult): String =
"Apologies, we couldn't infer if you confirmed or not. " +
"Please indicate \"yes\" or \"no\" if the following is correct:\n\n" +
s"Name: ${result.fullName.getOrElse("None")}\n" +
s"Email: ${result.email.getOrElse("None")}\n" +
s"Cellphone: ${result.cellphone.getOrElse("None")}"

}
24 changes: 9 additions & 15 deletions src/xyz/didx/ai/model/AgentScript.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,21 @@ object AgentScript {
"Name; Email; Cellphone. "
}

val endMessage = "When receiving your first message from a user, begin asking for the info you still need. " +
"They can give one attribute at a time, or all at once. " +
"If a user has already given their name, email or cellphone in the chat, or if you already know it, then you shouldn't ask them again." +
"Be friendly."
val endMessage = "Prompt the user until you have the required info. " +
"If a user has already given their name, email or cellphone in the chat, then you shouldn't ask them again. " +
"Be friendly. When receiving a first message from a user, ask for the info you still need."

val fullMessage = s"$baseMessage $conditionalMessage $endMessage"
new JvmPromptBuilder().addSystemMessage(fullMessage)
}

def createConfirmationBuilder(onboardingResult: OnboardingResult): PromptBuilder = {
def createConfirmationBuilder(): PromptBuilder = {
val baseMessage =
"You are Yoma, an onboarding assistant! " +
"Your job is to receive confirmation from the user, whether the data we've recorded for that user is correct. " +
"We have the following data for them:\n" +
s"Name: ${onboardingResult.fullName.getOrElse("None")}\n" +
s"Email: ${onboardingResult.email.getOrElse("None")}\n" +
s"Cellphone: ${onboardingResult.cellphone.getOrElse("None")}\n" +
"Send this recorded data to the user, and ask them to please confirm if it's correct or not. " +
"They might respond with something like yes, indeed, correct, of course, :+1+, a thumbs up emoji, or other slang like shap - all of this would confirm their data (confirmed = True) " +
"If they respond with something like no, not correct, incorrect, of course not, :-1+, a thumbs down emoji, or other slang like wtf - all of this would confirm their data is incorrect (confirmed = False)" +
"If they give an unclear, blank, neutral or irrelevant response, we'll consider this to be confirmed = None, in which case you will kindly prompt them again!"
"Your job is to receive confirmation from the user - whether the data we've recorded is correct or not. " +
"They might respond with: yes, indeed, correct, of course, :+1+, a thumbs up emoji, slang like shap, or other general confirmation - all of this would confirm their data (confirmed = True). " +
"If they respond with: no, not correct, incorrect, of course not, :-1+, a thumbs down emoji, slang like wtf, or other general rejection - all of this would confirm their data is incorrect (confirmed = False). " +
"If they give an unclear, blank, neutral or irrelevant response, we'll consider this to be confirmed = None. " +
"Process their response and provide us with an Optional[Boolean]. confirmed = True, False, or None. "

new JvmPromptBuilder().addSystemMessage(baseMessage)
}
Expand Down
4 changes: 3 additions & 1 deletion src/xyz/didx/ai/model/ChatResult.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ case class OnboardingResult(

case class ConfirmedOnboardingResult(
@Description("The next message that you want to send to the user") nextMessageToUser: String,
@Description("User has confirmed that the recorded data is correct") confirmed: Option[Boolean] = None
@Description(
"True, False, or None, to indicate whether user has confirmed or not"
) userHasConfirmedOptionalBool: Option[Boolean] = None
) derives SerialDescriptor,
Decoder