Last active
September 4, 2024 10:55
-
-
Save israelias/9f7cbdb9017fd179c6110216f3daf913 to your computer and use it in GitHub Desktop.
lex-web-ui ultimate refresh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* lex-web-ui/src/store/actions.js | |
* Ultimate restart action (automated when user arrives at "start module" | |
* typically on `QID: Startmodule` or utterance "restart/start over" or `QID: Restart` | |
* | |
* we add a message.label and show only message.label to circumvent showing `QID: <module>` to user | |
*/ | |
import LexClient from '@/lib/lex/client'; | |
// non-state variables that may be mutated outside of store | |
// set via initializers at run time | |
// ... | |
let lexClient; | |
// ... | |
export default { | |
/** ... */ | |
/** | |
* SP-Edit | |
* sends the initial utterance configured in the Lex config | |
* to start the conversation. | |
* | |
* Originally: | |
* It dispatches the postTextMessage action to send the utterance | |
* | |
* Modified: | |
* If the initialUtteranceSent flag is false in state, it sends the configured | |
* initialUtterance text. | |
* | |
* If initialUtteranceSent is true, it sends a "Restart" message to restart the | |
* conversation. | |
*/ | |
sendInitialUtterance(context) { | |
if (context.state.config.lex.initialUtterance) { | |
let message = { | |
type: context.state.config.ui.hideButtonMessageBubble ? 'button' : 'human', | |
text: context.state.config.lex.initialUtterance, | |
label: 'Restart', | |
}; | |
if (!context.state.initialUtteranceSent) { | |
console.info('Sending initial utterance as configured'); | |
message.text = context.state.config.lex.initialUtterance; | |
} else { | |
console.info('Sending initial utterance as Restart'); | |
message.label = 'Restart'; | |
} | |
context.dispatch('postTextMessage', message); | |
} | |
}, | |
/** /SP-Edit */ | |
/** ... */ | |
// see SP-Addition in this long method | |
postTextMessage(context, message) { | |
if (context.state.isSFXOn && !context.state.lex.isPostTextRetry) { | |
context.dispatch('playSound', context.state.config.ui.messageSentSFX); | |
} | |
return context.dispatch('interruptSpeechConversation') | |
.then(() => { | |
/** | |
* SP-Addition | |
* If messsage.text === initialUtterance or "Restart", | |
* Start a new session, which issues a new sessionId. | |
*/ | |
const initialUtterance = context.state.config.lex.initialUtterance | |
? context.state.config.lex.initialUtterance | |
: ""; | |
const qidInitialUtterance = `QID::${initialUtterance}`; | |
if ( | |
initialUtterance.length > 0 && | |
(message.text === initialUtterance || | |
message.text === qidInitialUtterance || | |
message.label === "Restart" | |
) | |
) { | |
console.info('postTextMessage: triggered initialUtterance', message.text); | |
if (lexClient) { | |
lexClient.createSessionId(); | |
console.info('A new session id has been issued'); | |
console.info('Clearing messages', context.state.messages); | |
context.commit('clearMessages'); | |
console.info('Messages cleared', context.state.messages); | |
console.info('Clearing utterance', context.state.utteranceStack); | |
context.commit('clearUtteranceStack'); | |
console.info('Utterances cleared', context.state.utteranceStack); | |
return Promise.resolve(); | |
} | |
} | |
/** /SP-Addition */ | |
return Promise.resolve(); | |
}) | |
/** ... */ | |
/** SKIP REST OF THIS METHOD HAS NOT BEEN MODIFIED */ | |
/** ... */ | |
.then(() => { | |
/** ... */ | |
}) | |
.then(() => { | |
/** ... */ | |
}) | |
.then(() => { | |
/** ... */ | |
}) | |
.then((response) => { | |
/** ... */ | |
.then(() => { | |
/** ... */ | |
}) | |
.catch((error) => { | |
/** ... */ | |
}); | |
}, | |
/** ... */ | |
/** | |
* SP-Edit | |
* the action the resets the chat window when saveHistory: true | |
* Adds commit to clear the utterance stack along with the messages | |
* adds dispatch to send initial utterance | |
* along with initial text with bot if it's set | |
* @todo unused and consider adding logic between initialText and initialUtterance | |
*/ | |
resetHistory(context) { | |
context.commit('clearMessages'); | |
context.commit('clearUtteranceStack'); | |
context.dispatch('sendInitialUtterance'); | |
context.commit('pushMessage', { | |
type: 'bot', | |
text: context.state.config.lex.initialText, | |
}); | |
}, | |
/** /SP-Edit */ | |
/** ... */ | |
/** | |
* SP-Addition | |
* requires restartButton to be enabled in config.json (an SP-Addition in lex-web-ui-config.json) | |
* renders Menu.Restartwhen this is enabled | |
* | |
* restartSession restarts the conversation session by: | |
* | |
* - Setting initialUtteranceSent to false | |
* - Clearing messages | |
* - Clearing utterance stack | |
* - Dispatching sendInitialUtterance after delay | |
* - Setting initialUtteranceSent to true | |
* - Creating new session ID in Lex | |
* - Pushing initial bot message | |
* | |
* sending initialText at the end does not appear to have consequence to this action | |
* as it appears: we never configure both (at dev discretion) | |
* | |
* !IMPORTANT does the same thing as the condition block in postTextMessage (but in a single run) to offer to user as a "Restart" button | |
* @see lex-web-ui/src/components/ToolbarContainer.vue | |
*/ | |
restartSession(context) { | |
console.info('restartSession: setting initialUtteranceSent to false'); | |
context.commit('setInitialUtteranceSent', false); | |
if (lexClient) { | |
console.info('Clearing messages', context.state.messages); | |
context.commit('clearMessages'); | |
console.info('Messages cleared', context.state.messages); | |
console.info('Clearing utterance', context.state.utteranceStack); | |
context.dispatch('clearUtteranceStack'); | |
console.info('Utterances cleared', context.state.utteranceStack); | |
console.info('Dispatching innitial utterance'); | |
setTimeout(() => context.dispatch('sendInitialUtterance'), 500); | |
context.commit('setInitialUtteranceSent', true); | |
console.info('innitial utterance dispatched'); | |
lexClient.createSessionId(); | |
console.info('A new session id has been issued'); | |
context.commit('pushMessage', { | |
type: 'bot', | |
text: context.state.config.lex.initialText, | |
}); | |
} | |
}, | |
/** /SP-Addition */ | |
/** ... */ | |
/** | |
* SP-Addition | |
* just a dispatch wrapper to commit to mutations of the same name | |
* unused | |
*/ | |
clearUtteranceStack(context) { | |
context.commit('clearUtteranceStack'); | |
}, | |
/** /SP-Addition */ | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// lex-web-ui/src/lib/lex/client.js | |
import { v4 as uuidv4 } from "uuid"; | |
/** ... */ | |
export default class { | |
botV2Id; | |
botV2AliasId; | |
botV2LocaleId; | |
isV2Bot; | |
constructor({ | |
botName, | |
botAlias = '$LATEST', | |
userId, | |
lexRuntimeClient, | |
botV2Id, | |
botV2AliasId, | |
botV2LocaleId, | |
lexRuntimeV2Client, | |
}) { | |
if (!botName || !lexRuntimeClient || !lexRuntimeV2Client || | |
typeof botV2Id === 'undefined' || | |
typeof botV2AliasId === 'undefined' || | |
typeof botV2LocaleId === 'undefined' | |
) { | |
console.error(`botName: ${botName} botV2Id: ${botV2Id} botV2AliasId ${botV2AliasId} ` + | |
`botV2LocaleId ${botV2LocaleId} lexRuntimeClient ${lexRuntimeClient} ` + | |
`lexRuntimeV2Client ${lexRuntimeV2Client}`); | |
throw new Error('invalid lex client constructor arguments'); | |
} | |
this.botName = botName; | |
this.botAlias = botAlias; | |
/** | |
* SP-Edit | |
* Initialize userId to a v4-compliant uuid | |
*/ | |
this.userId = userId || uuidv4(); | |
/** /SP-Edit */ | |
this.botV2Id = botV2Id; | |
this.botV2AliasId = botV2AliasId; | |
this.botV2LocaleId = botV2LocaleId; | |
this.isV2Bot = (this.botV2Id.length > 0); | |
this.lexRuntimeClient = this.isV2Bot ? lexRuntimeV2Client : lexRuntimeClient; | |
this.credentials = this.lexRuntimeClient.config.credentials; | |
} | |
initCredentials(credentials) { | |
this.credentials = credentials; | |
this.lexRuntimeClient.config.credentials = this.credentials; | |
/** | |
* SP-Edit | |
* Do not set userId from Cognito | |
*/ | |
this.userId = this.userId ? this.userId : uuidv4(); | |
// this.userId = (credentials.identityId) ? | |
// credentials.identityId : | |
// this.userId; | |
/** /SP-Edit */ | |
} | |
/** ... */ | |
startNewSession() { | |
let putSessionReq; | |
/** | |
* SP-Edit | |
* content.length must be > 0 on init when dialogaction.type is ElicitIntent if doing it for v2 | |
* set empty sessionState object instead | |
* | |
* @see {@link 'https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/lex-runtime-v2/command/PutSessionCommand/' PutSessionCommand} | |
*/ | |
/** /SP-Edit */ | |
if (this.isV2Bot) { | |
putSessionReq = this.lexRuntimeClient.putSession({ | |
botAliasId: this.botV2AliasId, | |
botId: this.botV2Id, | |
localeId: this.botV2LocaleId, | |
sessionId: this.userId, | |
sessionState: { | |
}, | |
}); | |
} else { | |
putSessionReq = this.lexRuntimeClient.putSession({ | |
botAlias: this.botAlias, | |
botName: this.botName, | |
userId: this.userId, | |
dialogAction: { | |
type: 'ElicitIntent', | |
}, | |
}); | |
} | |
return this.credentials.getPromise() | |
.then(creds => creds && this.initCredentials(creds)) | |
.then(() => putSessionReq.promise()); | |
} | |
/** ... */ | |
/** | |
* SP-Addition | |
* Make sessionId v4-compliant | |
* @returns {string} new uuid v4 string | |
*/ | |
createSessionId() { | |
console.info('createSessionId triggered: previous id', this.userId); | |
this.userId = uuidv4(); | |
console.info('rcreatesessionid done new id:', this.userId); | |
} | |
/** /SP-Addition */ | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- lex-web-ui/src/components/ToolbarContainer.vue --> | |
<!-- Ultimate Restart Button (user initiated) --> | |
<template> | |
<!-- eslint-disable max-len --> | |
<!-- v-toolbar --> | |
<!-- v-menu --> | |
<!-- v-list --> | |
<!-- if enableLogin --> | |
<!-- if isSaveHistory --> | |
<!-- etc --> | |
<!-- SP-Addition --> | |
<!-- Restart but as a button for user to trigger a restart action --> | |
<v-list-tile v-if="shouldRenderRestartButton"> | |
<v-list-tile-title v-on:click="requestRestartSession" aria-label="restart session"> | |
<v-icon> | |
{{ items[5].icon }} | |
</v-icon> | |
{{ items[5].title }} | |
</v-list-tile-title> | |
</v-list-tile> | |
<!-- /SP-Addition --> | |
<script> | |
import { chatMode, liveChatStatus } from '@/store/state'; | |
export default { | |
/** ... */ | |
computed: { | |
/** ... */ | |
/** | |
* SP-Addition | |
* Offers an SP1-specific restart button. | |
*/ | |
shouldRenderRestartButton() { | |
return this.$store.state.config.ui.restartButton; | |
}, | |
/** /SP-Addition */ | |
}, | |
methods: { | |
/** ... */ | |
/** | |
* SP-Edit | |
* dispatches an action to restart a session with logic to issue | |
* new credentials | |
* @see restartSession in lex-web-ui/src/store/actions.js | |
*/ | |
requestRestartSession() { | |
this.$store.dispatch('restartSession'); | |
}, | |
/** /SP-Edit */ | |
}, | |
}; | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment