mirror of
https://github.com/leon-ai/leon.git
synced 2024-12-25 17:54:43 +03:00
feat(server): introduce basic concept of action loop
This commit is contained in:
parent
7a9db1363d
commit
c5b3840082
@ -9,6 +9,7 @@ const defaultActiveContext = {
|
||||
currentEntities: [],
|
||||
entities: [],
|
||||
slots: { },
|
||||
isInActionLoop: false,
|
||||
nextAction: null,
|
||||
originalUtterance: null,
|
||||
activatedAt: 0
|
||||
@ -50,6 +51,7 @@ class Conversation {
|
||||
set activeContext (contextObj) {
|
||||
const {
|
||||
slots,
|
||||
isInActionLoop,
|
||||
nluDataFilePath,
|
||||
actionName,
|
||||
lang,
|
||||
@ -81,6 +83,7 @@ class Conversation {
|
||||
currentEntities: [],
|
||||
entities: [],
|
||||
slots: { },
|
||||
isInActionLoop,
|
||||
nextAction,
|
||||
originalUtterance: contextObj.originalUtterance,
|
||||
activatedAt: Date.now()
|
||||
@ -112,6 +115,7 @@ class Conversation {
|
||||
currentEntities: entities,
|
||||
entities,
|
||||
slots: { },
|
||||
isInActionLoop,
|
||||
nextAction: null,
|
||||
originalUtterance: contextObj.originalUtterance,
|
||||
activatedAt: Date.now()
|
||||
|
@ -92,7 +92,7 @@ class Nlu {
|
||||
* TODO: split this method into several methods
|
||||
*/
|
||||
process (utterance, opts) {
|
||||
console.log('this.conv.activeContext', this.conv.activeContext)
|
||||
console.log('process() start this.conv.activeContext', this.conv.activeContext)
|
||||
const processingTimeStart = Date.now()
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
@ -133,34 +133,66 @@ class Nlu {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: make difference between context that needs slots and the ones who does not
|
||||
// TODO: this case is only for slots context
|
||||
// TODO: an action requiring slots must always have a next_action
|
||||
console.log('THIS.CONV', this.conv.activeContext)
|
||||
// Pre NLU processing according to the active context if there is one
|
||||
if (this.conv.hasActiveContext()) {
|
||||
const processedData = await this.slotFill(utterance, opts)
|
||||
console.log('processedData (slot filled over)', processedData)
|
||||
|
||||
if (processedData && Object.keys(processedData).length > 0) {
|
||||
processedData.nextAction = 'guess'
|
||||
// Set new context with the next action if there is one
|
||||
if (processedData.nextAction) {
|
||||
this.conv.activeContext = {
|
||||
lang: this.brain.lang,
|
||||
slots: { },
|
||||
originalUtterance: processedData.utterance,
|
||||
nluDataFilePath: processedData.nluDataFilePath,
|
||||
actionName: processedData.nextAction,
|
||||
domain: processedData.classification.domain,
|
||||
intent: `${processedData.classification.skill}.${processedData.nextAction}`,
|
||||
entities: []
|
||||
// When the active context is in an action loop, then directly trigger the action
|
||||
if (this.conv.activeContext.isInActionLoop) {
|
||||
const { domain, intent } = this.conv.activeContext
|
||||
const [skillName, actionName] = intent.split('.')
|
||||
const nluDataFilePath = join(process.cwd(), 'skills', domain, skillName, `nlu/${this.brain.lang}.json`)
|
||||
this.nluResultObj = {
|
||||
...this.nluResultObj,
|
||||
slots: this.conv.activeContext.slots,
|
||||
utterance,
|
||||
nluDataFilePath,
|
||||
classification: {
|
||||
domain,
|
||||
skill: skillName,
|
||||
action: actionName,
|
||||
confidence: 1
|
||||
}
|
||||
|
||||
console.log('NEW ACTIVE CONTEXT', this.conv.activeContext)
|
||||
}
|
||||
this.nluResultObj.entities = await this.ner.extractEntities(
|
||||
this.brain.lang,
|
||||
nluDataFilePath,
|
||||
this.nluResultObj
|
||||
)
|
||||
|
||||
const processedData = await this.brain.execute(this.nluResultObj, { mute: opts.mute })
|
||||
return resolve(processedData)
|
||||
}
|
||||
|
||||
return resolve(processedData)
|
||||
// TODO: make difference between context that needs slots and the ones who does not
|
||||
// TODO: this case is only for slots context
|
||||
// TODO: an action requiring slots must always have a next_action
|
||||
console.log('THIS.CONV', this.conv.activeContext)
|
||||
// When the active context has slots filled
|
||||
if (Object.keys(this.conv.activeContext.slots).length > 0) {
|
||||
const processedData = await this.slotFill(utterance, opts)
|
||||
console.log('processedData (slot filled over)', processedData)
|
||||
|
||||
if (processedData && Object.keys(processedData).length > 0) {
|
||||
processedData.nextAction = 'guess'
|
||||
// Set new context with the next action if there is one
|
||||
if (processedData.nextAction) {
|
||||
this.conv.activeContext = {
|
||||
lang: this.brain.lang,
|
||||
slots: { },
|
||||
isInActionLoop: true, // TODO: dynamic value according to the skill output
|
||||
originalUtterance: processedData.utterance,
|
||||
nluDataFilePath: processedData.nluDataFilePath,
|
||||
actionName: processedData.nextAction,
|
||||
domain: processedData.classification.domain,
|
||||
intent: `${processedData.classification.skill}.${processedData.nextAction}`,
|
||||
entities: []
|
||||
}
|
||||
|
||||
console.log('NEW ACTIVE CONTEXT', this.conv.activeContext)
|
||||
}
|
||||
}
|
||||
|
||||
return resolve(processedData)
|
||||
}
|
||||
}
|
||||
|
||||
const result = await this.nlp.process(utterance)
|
||||
@ -302,8 +334,8 @@ class Nlu {
|
||||
}
|
||||
}
|
||||
|
||||
const shouldLoop = await this.routeSlotFilling(intent)
|
||||
if (shouldLoop) {
|
||||
const shouldSlotLoop = await this.routeSlotFilling(intent)
|
||||
if (shouldSlotLoop) {
|
||||
return resolve({ })
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,9 @@
|
||||
"skill": "is_it_down",
|
||||
"action": "run",
|
||||
"utterance": "Check if github.com, mozilla.org and twitter.com are up",
|
||||
"entities": [
|
||||
"slots": {},
|
||||
"entities": [],
|
||||
"current_entities": [
|
||||
{
|
||||
"sourceText": "github.com",
|
||||
"utteranceText": "github.com",
|
||||
|
@ -11,6 +11,7 @@ def guess(params):
|
||||
nb_to_guess = 42 # TODO: pick up from DB
|
||||
|
||||
# Find entities
|
||||
# TODO: if no number entity found, then break the action loop
|
||||
for item in params['entities']:
|
||||
if item['entity'] == 'number':
|
||||
given_nb = item['resolution']['value']
|
||||
@ -18,8 +19,6 @@ def guess(params):
|
||||
if given_nb == nb_to_guess:
|
||||
return utils.output('end', 'guessed', '....CONGRATS....')
|
||||
if nb_to_guess < given_nb:
|
||||
# TODO: enable loop
|
||||
return utils.output('end', 'smaller', utils.translate('smaller')
|
||||
return utils.output('end', 'smaller', utils.translate('smaller'))
|
||||
if nb_to_guess > given_nb:
|
||||
# TODO: enable loop
|
||||
return utils.output('end', 'bigger', utils.translate('bigger')
|
||||
return utils.output('end', 'bigger', utils.translate('bigger'))
|
||||
|
Loading…
Reference in New Issue
Block a user