1
1
mirror of https://github.com/leon-ai/leon.git synced 2024-12-25 09:44:22 +03:00

refactor: switch from skill NLU config to skill config naming

This commit is contained in:
louistiti 2022-08-20 22:35:34 +08:00
parent 141c89ecbf
commit 01f7515e6f
No known key found for this signature in database
GPG Key ID: 7ECA3DD523793FE6
43 changed files with 41 additions and 41 deletions

View File

@ -37,7 +37,7 @@ def translate(key, dict = { }):
output = '' output = ''
variables = { } variables = { }
file = open(path.join(dirname, '../../skills', intent_obj['domain'], intent_obj['skill'], 'nlu', intent_obj['lang'] + '.json'), 'r', encoding = 'utf8') file = open(path.join(dirname, '../../skills', intent_obj['domain'], intent_obj['skill'], 'config', intent_obj['lang'] + '.json'), 'r', encoding = 'utf8')
obj = loads(file.read()) obj = loads(file.read())
file.close() file.close()

View File

@ -11,7 +11,7 @@ dotenv.config()
/** /**
* Generate skills endpoints script * Generate skills endpoints script
* Parse and convert skills NLU config into a JSON file understandable by Fastify * Parse and convert skills config into a JSON file understandable by Fastify
* to dynamically generate endpoints so skills can be accessible over HTTP * to dynamically generate endpoints so skills can be accessible over HTTP
*/ */
export default () => new Promise(async (resolve, reject) => { export default () => new Promise(async (resolve, reject) => {
@ -40,7 +40,7 @@ export default () => new Promise(async (resolve, reject) => {
for (let j = 0; j < skillKeys.length; j += 1) { for (let j = 0; j < skillKeys.length; j += 1) {
const skillFriendlyName = skillKeys[j] const skillFriendlyName = skillKeys[j]
const currentSkill = currentDomain.skills[skillFriendlyName] const currentSkill = currentDomain.skills[skillFriendlyName]
const fileInfo = fs.statSync(path.join(currentSkill.path, 'nlu', `${lang}.json`)) const fileInfo = fs.statSync(path.join(currentSkill.path, 'config', `${lang}.json`))
const mtime = fileInfo.mtime.getTime() const mtime = fileInfo.mtime.getTime()
if (mtime > mtimeEndpoints) { if (mtime > mtimeEndpoints) {
@ -62,7 +62,7 @@ export default () => new Promise(async (resolve, reject) => {
// Force if a language is given // Force if a language is given
if (isFileNeedToBeGenerated) { if (isFileNeedToBeGenerated) {
log.info('Parsing skills NLU configuration...') log.info('Parsing skills configuration...')
for (let i = 0; i < domainKeys.length; i += 1) { for (let i = 0; i < domainKeys.length; i += 1) {
const currentDomain = domains[domainKeys[i]] const currentDomain = domains[domainKeys[i]]
@ -73,8 +73,8 @@ export default () => new Promise(async (resolve, reject) => {
const skillFriendlyName = skillKeys[j] const skillFriendlyName = skillKeys[j]
const currentSkill = currentDomain.skills[skillFriendlyName] const currentSkill = currentDomain.skills[skillFriendlyName]
const nluFilePath = path.join(currentSkill.path, 'nlu', `${lang}.json`) const configFilePath = path.join(currentSkill.path, 'config', `${lang}.json`)
const { actions } = JSON.parse(fs.readFileSync(nluFilePath, 'utf8')) const { actions } = JSON.parse(fs.readFileSync(configFilePath, 'utf8'))
const actionsKeys = Object.keys(actions) const actionsKeys = Object.keys(actions)
for (let k = 0; k < actionsKeys.length; k += 1) { for (let k = 0; k < actionsKeys.length; k += 1) {

View File

@ -26,15 +26,15 @@ export default (lang, nlp) => new Promise(async (resolve) => {
const { name: skillName } = currentDomain.skills[skillKeys[j]] const { name: skillName } = currentDomain.skills[skillKeys[j]]
const currentSkill = currentDomain.skills[skillKeys[j]] const currentSkill = currentDomain.skills[skillKeys[j]]
log.info(`[${lang}] Using "${skillKeys[j]}" skill NLU data`) log.info(`[${lang}] Using "${skillKeys[j]}" skill config data`)
const nluFilePath = path.join(currentSkill.path, 'nlu', `${lang}.json`) const configFilePath = path.join(currentSkill.path, 'config', `${lang}.json`)
if (fs.existsSync(nluFilePath)) { if (fs.existsSync(configFilePath)) {
const { const {
actions, actions,
variables variables
} = await json.loadNluData(nluFilePath, lang) // eslint-disable-line no-await-in-loop } = await json.loadConfigData(configFilePath, lang) // eslint-disable-line no-await-in-loop
const actionsKeys = Object.keys(actions) const actionsKeys = Object.keys(actions)
for (let k = 0; k < actionsKeys.length; k += 1) { for (let k = 0; k < actionsKeys.length; k += 1) {

View File

@ -20,10 +20,10 @@ export default (lang, nlp) => new Promise(async (resolve) => {
skillKeys.forEach(async (skillName) => { skillKeys.forEach(async (skillName) => {
const currentSkill = currentDomain.skills[skillName] const currentSkill = currentDomain.skills[skillName]
const nluFilePath = path.join(currentSkill.path, 'nlu', `${lang}.json`) const configFilePath = path.join(currentSkill.path, 'config', `${lang}.json`)
if (fs.existsSync(nluFilePath)) { if (fs.existsSync(configFilePath)) {
const { resolvers } = await json.loadNluData(nluFilePath, lang) const { resolvers } = await json.loadConfigData(configFilePath, lang)
if (resolvers) { if (resolvers) {
const resolversKeys = Object.keys(resolvers) const resolversKeys = Object.keys(resolvers)

View File

@ -158,8 +158,8 @@ class Brain {
executionTime executionTime
}) })
} else { } else {
const { nluDataFilePath, classification: { action: actionName } } = obj const { configDataFilePath, classification: { action: actionName } } = obj
const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8')) const { actions } = JSON.parse(fs.readFileSync(configDataFilePath, 'utf8'))
const action = actions[actionName] const action = actions[actionName]
const { type: actionType } = action const { type: actionType } = action
const nextAction = action.next_action ? actions[action.next_action] : null const nextAction = action.next_action ? actions[action.next_action] : null
@ -360,10 +360,10 @@ class Brain {
* "Dialog" action skill execution * "Dialog" action skill execution
*/ */
const nluFilePath = path.join( const configFilePath = path.join(
process.cwd(), 'skills', obj.classification.domain, obj.classification.skill, 'nlu', `${this._lang}.json` process.cwd(), 'skills', obj.classification.domain, obj.classification.skill, 'config', `${this._lang}.json`
) )
const { actions, entities } = await json.loadNluData(nluFilePath, this._lang) const { actions, entities } = await json.loadConfigData(configFilePath, this._lang)
const utteranceHasEntities = obj.entities.length > 0 const utteranceHasEntities = obj.entities.length > 0
const { answers: rawAnswers } = obj const { answers: rawAnswers } = obj
let answers = rawAnswers let answers = rawAnswers

View File

@ -53,7 +53,7 @@ class Conversation {
const { const {
slots, slots,
isInActionLoop, isInActionLoop,
nluDataFilePath, configDataFilePath,
actionName, actionName,
lang, lang,
domain, domain,
@ -63,7 +63,7 @@ class Conversation {
const slotKeys = Object.keys(slots) const slotKeys = Object.keys(slots)
const [skillName] = intent.split('.') const [skillName] = intent.split('.')
const newContextName = `${domain}.${skillName}` const newContextName = `${domain}.${skillName}`
const { actions } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8')) const { actions } = JSON.parse(fs.readFileSync(configDataFilePath, 'utf8'))
// Grab next action from the NLU data file // Grab next action from the NLU data file
const { next_action: nextAction } = actions[actionName] const { next_action: nextAction } = actions[actionName]

View File

@ -24,7 +24,7 @@ const defaultNluResultObj = {
currentResolvers: [], currentResolvers: [],
resolvers: [], resolvers: [],
slots: null, slots: null,
nluDataFilePath: null, configDataFilePath: null,
answers: [], // For dialog action type answers: [], // For dialog action type
classification: { classification: {
domain: null, domain: null,
@ -241,12 +241,12 @@ class Nlu {
async handleActionLoop (utterance, opts) { async handleActionLoop (utterance, opts) {
const { domain, intent } = this.conv.activeContext const { domain, intent } = this.conv.activeContext
const [skillName, actionName] = intent.split('.') const [skillName, actionName] = intent.split('.')
const nluDataFilePath = join(process.cwd(), 'skills', domain, skillName, `nlu/${this.brain.lang}.json`) const configDataFilePath = join(process.cwd(), 'skills', domain, skillName, `config/${this.brain.lang}.json`)
this.nluResultObj = { this.nluResultObj = {
...defaultNluResultObj, // Reset entities, slots, etc. ...defaultNluResultObj, // Reset entities, slots, etc.
slots: this.conv.activeContext.slots, slots: this.conv.activeContext.slots,
utterance, utterance,
nluDataFilePath, configDataFilePath,
classification: { classification: {
domain, domain,
skill: skillName, skill: skillName,
@ -256,11 +256,11 @@ class Nlu {
} }
this.nluResultObj.entities = await this.ner.extractEntities( this.nluResultObj.entities = await this.ner.extractEntities(
this.brain.lang, this.brain.lang,
nluDataFilePath, configDataFilePath,
this.nluResultObj this.nluResultObj
) )
const { actions, resolvers } = JSON.parse(fs.readFileSync(nluDataFilePath, 'utf8')) const { actions, resolvers } = JSON.parse(fs.readFileSync(configDataFilePath, 'utf8'))
const action = actions[this.nluResultObj.classification.action] const action = actions[this.nluResultObj.classification.action]
const { const {
name: expectedItemName, type: expectedItemType name: expectedItemName, type: expectedItemType
@ -369,7 +369,7 @@ class Nlu {
slots: processedData.slots, slots: processedData.slots,
isInActionLoop: !!processedData.nextAction.loop, isInActionLoop: !!processedData.nextAction.loop,
originalUtterance: processedData.utterance, originalUtterance: processedData.utterance,
nluDataFilePath: processedData.nluDataFilePath, configDataFilePath: processedData.configDataFilePath,
actionName: processedData.action.next_action, actionName: processedData.action.next_action,
domain: processedData.classification.domain, domain: processedData.classification.domain,
intent: `${processedData.classification.skill}.${processedData.action.next_action}`, intent: `${processedData.classification.skill}.${processedData.action.next_action}`,
@ -510,13 +510,13 @@ class Nlu {
log.title('NLU') log.title('NLU')
log.success(`Intent found: ${this.nluResultObj.classification.skill}.${this.nluResultObj.classification.action} (domain: ${this.nluResultObj.classification.domain})`) log.success(`Intent found: ${this.nluResultObj.classification.skill}.${this.nluResultObj.classification.action} (domain: ${this.nluResultObj.classification.domain})`)
const nluDataFilePath = join(process.cwd(), 'skills', this.nluResultObj.classification.domain, this.nluResultObj.classification.skill, `nlu/${this.brain.lang}.json`) const configDataFilePath = join(process.cwd(), 'skills', this.nluResultObj.classification.domain, this.nluResultObj.classification.skill, `config/${this.brain.lang}.json`)
this.nluResultObj.nluDataFilePath = nluDataFilePath this.nluResultObj.configDataFilePath = configDataFilePath
try { try {
this.nluResultObj.entities = await this.ner.extractEntities( this.nluResultObj.entities = await this.ner.extractEntities(
this.brain.lang, this.brain.lang,
nluDataFilePath, configDataFilePath,
this.nluResultObj this.nluResultObj
) )
} catch (e) /* istanbul ignore next */ { } catch (e) /* istanbul ignore next */ {
@ -552,7 +552,7 @@ class Nlu {
slots: { }, slots: { },
isInActionLoop: false, isInActionLoop: false,
originalUtterance: this.nluResultObj.utterance, originalUtterance: this.nluResultObj.utterance,
nluDataFilePath: this.nluResultObj.nluDataFilePath, configDataFilePath: this.nluResultObj.configDataFilePath,
actionName: this.nluResultObj.classification.action, actionName: this.nluResultObj.classification.action,
domain: this.nluResultObj.classification.domain, domain: this.nluResultObj.classification.domain,
intent, intent,
@ -574,7 +574,7 @@ class Nlu {
slots: { }, slots: { },
isInActionLoop: !!processedData.nextAction.loop, isInActionLoop: !!processedData.nextAction.loop,
originalUtterance: processedData.utterance, originalUtterance: processedData.utterance,
nluDataFilePath: processedData.nluDataFilePath, configDataFilePath: processedData.configDataFilePath,
actionName: processedData.action.next_action, actionName: processedData.action.next_action,
domain: processedData.classification.domain, domain: processedData.classification.domain,
intent: `${processedData.classification.skill}.${processedData.action.next_action}`, intent: `${processedData.classification.skill}.${processedData.action.next_action}`,
@ -614,7 +614,7 @@ class Nlu {
const { domain, intent } = this.conv.activeContext const { domain, intent } = this.conv.activeContext
const [skillName, actionName] = intent.split('.') const [skillName, actionName] = intent.split('.')
const nluDataFilePath = join(process.cwd(), 'skills', domain, skillName, `nlu/${this.brain.lang}.json`) const configDataFilePath = join(process.cwd(), 'skills', domain, skillName, `config/${this.brain.lang}.json`)
this.nluResultObj = { this.nluResultObj = {
...defaultNluResultObj, // Reset entities, slots, etc. ...defaultNluResultObj, // Reset entities, slots, etc.
@ -627,7 +627,7 @@ class Nlu {
} }
const entities = await this.ner.extractEntities( const entities = await this.ner.extractEntities(
this.brain.lang, this.brain.lang,
nluDataFilePath, configDataFilePath,
this.nluResultObj this.nluResultObj
) )
@ -657,7 +657,7 @@ class Nlu {
// Assign slots only if there is a next action // Assign slots only if there is a next action
slots: this.conv.activeContext.nextAction ? this.conv.activeContext.slots : { }, slots: this.conv.activeContext.nextAction ? this.conv.activeContext.slots : { },
utterance: this.conv.activeContext.originalUtterance, utterance: this.conv.activeContext.originalUtterance,
nluDataFilePath, configDataFilePath,
classification: { classification: {
domain, domain,
skill: skillName, skill: skillName,
@ -691,7 +691,7 @@ class Nlu {
slots, slots,
isInActionLoop: false, isInActionLoop: false,
originalUtterance: this.nluResultObj.utterance, originalUtterance: this.nluResultObj.utterance,
nluDataFilePath: this.nluResultObj.nluDataFilePath, configDataFilePath: this.nluResultObj.configDataFilePath,
actionName: this.nluResultObj.classification.action, actionName: this.nluResultObj.classification.action,
domain: this.nluResultObj.classification.domain, domain: this.nluResultObj.classification.domain,
intent, intent,
@ -701,7 +701,7 @@ class Nlu {
const notFilledSlot = this.conv.getNotFilledSlot() const notFilledSlot = this.conv.getNotFilledSlot()
// Loop for questions if a slot hasn't been filled // Loop for questions if a slot hasn't been filled
if (notFilledSlot) { if (notFilledSlot) {
const { actions } = JSON.parse(fs.readFileSync(this.nluResultObj.nluDataFilePath, 'utf8')) const { actions } = JSON.parse(fs.readFileSync(this.nluResultObj.configDataFilePath, 'utf8'))
const [currentSlot] = actions[this.nluResultObj.classification.action].slots const [currentSlot] = actions[this.nluResultObj.classification.action].slots
.filter(({ name }) => name === notFilledSlot.name) .filter(({ name }) => name === notFilledSlot.name)

View File

@ -3,10 +3,10 @@ import path from 'path'
const json = { } const json = { }
json.loadNluData = async (nluFilePath, lang) => { json.loadConfigData = async (configFilePath, lang) => {
const sharedDataPath = path.join(process.cwd(), 'core/data', lang) const sharedDataPath = path.join(process.cwd(), 'core/data', lang)
const nluData = JSON.parse(fs.readFileSync(nluFilePath, 'utf8')) const configData = JSON.parse(fs.readFileSync(configFilePath, 'utf8'))
const { entities } = nluData const { entities } = configData
// Load shared data entities if entity = 'xxx.json' // Load shared data entities if entity = 'xxx.json'
if (entities) { if (entities) {
@ -18,10 +18,10 @@ json.loadNluData = async (nluFilePath, lang) => {
} }
}) })
nluData.entities = entities configData.entities = entities
} }
return nluData return configData
} }
export default json export default json