mirror of
https://github.com/leon-ai/leon.git
synced 2024-11-27 16:16:48 +03:00
feat: annotate entities on the fly + prepare for dialog skill type and cross-domains data
This commit is contained in:
parent
cf6340b3ca
commit
4107932d00
2
.gitignore
vendored
2
.gitignore
vendored
@ -25,6 +25,6 @@ packages/**/config/config.json
|
||||
skills/**/src/config.json
|
||||
packages/**/data/db/*.json
|
||||
skills/**/memory/*.json
|
||||
server/src/data/leon-model.nlp
|
||||
core/data/leon-model.nlp
|
||||
package.json.backup
|
||||
.python-version
|
||||
|
1
scripts/assets/intent-object.json
Normal file
1
scripts/assets/intent-object.json
Normal file
@ -0,0 +1 @@
|
||||
{"lang":"en","domain":"leon","skill":"random_number","action":"run","utterance":"Give me a random number","entities":[]}
|
@ -1 +0,0 @@
|
||||
{"lang":"en","package":"leon","module":"randomnumber","action":"run","utterance":"Give me a random number","entities":[]}
|
@ -22,7 +22,7 @@ export default () => new Promise(async (resolve, reject) => {
|
||||
const googleCloudPath = 'server/src/config/voice/google-cloud.json'
|
||||
const watsonSttPath = 'server/src/config/voice/watson-stt.json'
|
||||
const watsonTtsPath = 'server/src/config/voice/watson-tts.json'
|
||||
const nlpModelPath = 'server/src/data/leon-model.nlp'
|
||||
const nlpModelPath = 'core/data/leon-model.nlp'
|
||||
const report = {
|
||||
can_run: { title: 'Run', type: 'error', v: true },
|
||||
can_run_module: { title: 'Run modules', type: 'error', v: true },
|
||||
|
@ -17,7 +17,7 @@ dotenv.config()
|
||||
* npm run train [en or fr]
|
||||
*/
|
||||
export default () => new Promise(async (resolve, reject) => {
|
||||
const modelFileName = 'server/src/data/leon-model.nlp'
|
||||
const modelFileName = 'core/data/leon-model.nlp'
|
||||
|
||||
try {
|
||||
const container = await containerBootstrap()
|
||||
@ -58,19 +58,31 @@ export default () => new Promise(async (resolve, reject) => {
|
||||
const nluFilePath = path.join(currentSkill.path, 'nlu', `${lang}.json`)
|
||||
|
||||
if (fs.existsSync(nluFilePath)) {
|
||||
const { actions } = JSON.parse(fs.readFileSync(nluFilePath, 'utf8'))
|
||||
const { actions, entities } = JSON.parse(fs.readFileSync(nluFilePath, 'utf8'))
|
||||
const actionsKeys = Object.keys(actions)
|
||||
|
||||
for (let k = 0; k < actionsKeys.length; k += 1) {
|
||||
const actionName = actionsKeys[k]
|
||||
const actionObj = actions[actionName]
|
||||
const { utterance_samples: utteranceSamples } = actionObj
|
||||
const { utterance_samples: utteranceSamples, answers } = actionObj
|
||||
|
||||
nlp.assignDomain(lang, `${skillName}.${actionName}`, currentDomain.name)
|
||||
|
||||
for (let l = 0; l < utteranceSamples.length; l += 1) {
|
||||
nlp.addDocument(lang, utteranceSamples[l], `${skillName}.${actionName}`)
|
||||
}
|
||||
|
||||
// Train NLG if the skill has a dialog type
|
||||
if (currentSkill.type === 'dialog') {
|
||||
for (let l = 0; l < answers?.length; l += 1) {
|
||||
nlp.addAnswer(lang, `${skillName}.${actionName}`, answers[l])
|
||||
}
|
||||
}
|
||||
|
||||
// Add entities annotations (@...)
|
||||
if (entities) {
|
||||
nlp.addEntities(entities, lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import domain from '@/helpers/domain'
|
||||
class Brain {
|
||||
constructor () {
|
||||
this._lang = 'en'
|
||||
this.broca = JSON.parse(fs.readFileSync(`${__dirname}/../data/${this._lang}.json`, 'utf8'))
|
||||
this.broca = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'core/data', this._lang, 'answers.json'), 'utf8'))
|
||||
this.process = { }
|
||||
this.interOutput = { }
|
||||
this.finalOutput = { }
|
||||
@ -55,7 +55,7 @@ class Brain {
|
||||
set lang (newLang) {
|
||||
this._lang = newLang
|
||||
// Update broca
|
||||
this.broca = JSON.parse(fs.readFileSync(`${__dirname}/../data/${this._lang}.json`, 'utf8'))
|
||||
this.broca = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'core/data', this._lang, 'answers.json'), 'utf8'))
|
||||
|
||||
if (process.env.LEON_TTS === 'true') {
|
||||
this._tts.init(this._lang, () => {
|
||||
|
@ -285,7 +285,7 @@ server.init = async () => {
|
||||
|
||||
// Load NLP model
|
||||
try {
|
||||
await nlu.loadModel(join(__dirname, '../../data/leon-model.nlp'))
|
||||
await nlu.loadModel(join(process.cwd(), 'core/data/leon-model.nlp'))
|
||||
} catch (e) {
|
||||
log[e.type](e.obj.message)
|
||||
}
|
||||
|
@ -19,10 +19,11 @@ domain.getDomainsObj = async () => {
|
||||
const skillPath = path.join(domainPath, skillFolders[i])
|
||||
|
||||
if (fs.statSync(skillPath).isDirectory()) {
|
||||
const { name: skillName } = JSON.parse(fs.readFileSync(path.join(skillPath, 'skill.json'), 'utf8'))
|
||||
const { name: skillName, type: skillType } = JSON.parse(fs.readFileSync(path.join(skillPath, 'skill.json'), 'utf8'))
|
||||
|
||||
skillObj[skillName] = {
|
||||
name: skillFolders[i],
|
||||
type: skillType,
|
||||
path: skillPath
|
||||
}
|
||||
}
|
||||
|
@ -7,21 +7,20 @@
|
||||
"Make me laugh",
|
||||
"Do you have jokes to tell me?",
|
||||
"I wanna laugh"
|
||||
],
|
||||
"answers": [
|
||||
"My email password has been hacked. That's the third time I've had to rename the cat.",
|
||||
"What does a baby computer call it's father? Data.",
|
||||
"My New Year's resolution is 4K.",
|
||||
"Any room is a panic room if you've lost your phone in it.",
|
||||
"Why was the JavaScript developer sad? Because he didn't Node how to Express himself.",
|
||||
"Why did the developer go broke? Because he used up all his cache.",
|
||||
"There are 10 types of people in the world: those who understand binary, and those who don't.",
|
||||
"Instagram is just Twitter for people who go outside.",
|
||||
"Human: What do we want?! Computer: Natural language processing! Human: When do we want it?! Computer: When do we want what?",
|
||||
"Is your name Wi-Fi? Because I'm feeling a connection."
|
||||
]
|
||||
}
|
||||
},
|
||||
"answers": {
|
||||
"jokes": [
|
||||
"My email password has been hacked. That's the third time I've had to rename the cat.",
|
||||
"What does a baby computer call it's father? Data.",
|
||||
"My New Year's resolution is 4K.",
|
||||
"Any room is a panic room if you've lost your phone in it.",
|
||||
"Why was the JavaScript developer sad? Because he didn't Node how to Express himself.",
|
||||
"Why did the developer go broke? Because he used up all his cache.",
|
||||
"There are 10 types of people in the world: those who understand binary, and those who don't.",
|
||||
"Instagram is just Twitter for people who go outside.",
|
||||
"Human: What do we want?! Computer: Natural language processing! Human: When do we want it?! Computer: When do we want what?",
|
||||
"Is your name Wi-Fi? Because I'm feeling a connection."
|
||||
]
|
||||
}
|
||||
"answers": { }
|
||||
}
|
||||
|
@ -7,27 +7,26 @@
|
||||
"Donne-moi une blague",
|
||||
"Je veux rire",
|
||||
"As-tu des blagues à raconter ?"
|
||||
],
|
||||
"answers": [
|
||||
"Le mot de passe de ma boîte de réception a été piraté. C'est la troisième fois que je dois renommer le chat.",
|
||||
"Combien de développeurs faut-t-il pour remplacer une ampoule grillée ? Aucun, c'est un problème hardware.",
|
||||
"T'as pris quoi comme résolution pour cette nouvelle année ? La 4K.",
|
||||
"Toute pièce est une salle de panique si vous avez perdu votre téléphone à l'intérieur.",
|
||||
"C'est l'histoire d'un administrateur qui configure ses variables d'environnement, et là... PATH le chemin !",
|
||||
"Tu sais pourquoi l'iPhone 6 se plie ? Parce que l'Apple Store.",
|
||||
"Dans le monde, il y a 10 catégories de personnes : celles qui connaissent le binaire et celles qui ne le connaissent pas.",
|
||||
"Instagram c'est en fait Twitter pour les gens qui sortent un peu.",
|
||||
"Un humain demande : qu'est-ce que tu veux ?! Un ordinateur répond : du traitement automatique du langage naturel ! L'humain : quand le voulons-nous ?! L'ordinateur : quand le voulons quoi ?",
|
||||
"Est-ce que votre nom est Wi-Fi ? Parce que je sens une connexion.",
|
||||
"Quand quelqu'un de triste joue aux jeux vidéo pour oublier, on peut dire qu'il se console.",
|
||||
"Quel Pokemon a une mitraillette ? Ratatatatatatatatata.",
|
||||
"Les filles c'est comme les noms de domaine. Celles que j'aime sont déjà prises.",
|
||||
"Que dit une mère à son fils geek quand le diner est servi ? Alt Tab !",
|
||||
"Quelle est la meilleure heure pour écouter de la musique ? Deezer.",
|
||||
"De nos jours, le zip ça devient rar..."
|
||||
]
|
||||
}
|
||||
},
|
||||
"answers": {
|
||||
"jokes": [
|
||||
"Le mot de passe de ma boîte de réception a été piraté. C'est la troisième fois que je dois renommer le chat.",
|
||||
"Combien de développeurs faut-t-il pour remplacer une ampoule grillée ? Aucun, c'est un problème hardware.",
|
||||
"T'as pris quoi comme résolution pour cette nouvelle année ? 4K.",
|
||||
"Toute pièce est une salle de panique si vous avez perdu votre téléphone à l'intérieur.",
|
||||
"C'est l'histoire d'un administrateur qui configure ses variables d'environnement, et là... PATH le chemin !",
|
||||
"Tu sais pourquoi l'iPhone 6 se plie ? Parce que l'Apple Store.",
|
||||
"Dans le monde, il y a 10 catégories de personnes : celles qui connaissent le binaire et celles qui ne le connaissent pas.",
|
||||
"Instagram c'est en fait Twitter pour les gens qui sortent un peu.",
|
||||
"Un humain demande : qu'est-ce que tu veux ?! Un ordinateur répond : du traitement automatique du langage naturel ! L'humain : quand le voulons-nous ?! L'ordinateur : quand le voulons quoi ?",
|
||||
"Est-ce que votre nom est Wi-Fi ? Parce que je sens une connexion.",
|
||||
"Quand quelqu'un de triste joue aux jeux vidéo pour oublier, on peut dire qu'il se console.",
|
||||
"Quel Pokemon a une mitraillette ? Ratatatatatatatatata.",
|
||||
"Les filles c'est comme les noms de domaine. Celles que j'aime sont déjà prises.",
|
||||
"Que dit une mère à son fils geek quand le diner est servi ? Alt Tab !",
|
||||
"Quelle est la meilleure heure pour écouter de la musique ? Deezer.",
|
||||
"De nos jours, le zip ça devient rar..."
|
||||
]
|
||||
}
|
||||
"answers": { }
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "Joke",
|
||||
"bridge": "python",
|
||||
"type": "dialog",
|
||||
"bridge": null,
|
||||
"version": "1.0.0",
|
||||
"description": "Leon says some jokes.",
|
||||
"author": {
|
||||
|
@ -2,17 +2,23 @@
|
||||
"actions": {
|
||||
"run": {
|
||||
"utterance_samples": [
|
||||
"Do you have something to say about Alexa?",
|
||||
"Tell me about the personal assistant Alexa",
|
||||
"Tell me about the personal assistant Cortana",
|
||||
"Do you have something to say about Cortana?",
|
||||
"Tell me about the personal assistant Siri",
|
||||
"Do you have something to say about Siri?",
|
||||
"Tell me about the personal assistant Google Assistant",
|
||||
"Do you have something to say about Google Assistant?"
|
||||
"Do you have something to say about @partnerAssistant?",
|
||||
"Tell me about the personal assistant @partnerAssistant",
|
||||
"I want to know more about @partnerAssistant",
|
||||
"Tell me something related to @partnerAssistant"
|
||||
]
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"partnerAssistant": {
|
||||
"options": {
|
||||
"Alexa": ["alexa"],
|
||||
"Cortana": ["cortana"],
|
||||
"Siri": ["siri"],
|
||||
"Google Assistant": ["google assistant"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"answers": {
|
||||
"alexa": [
|
||||
"Alexa is very kind and Amazon is teaching it many things. It was born in November 2014.",
|
||||
|
@ -2,17 +2,23 @@
|
||||
"actions": {
|
||||
"run": {
|
||||
"utterance_samples": [
|
||||
"Connais-tu quelque chose sur Alexa ?",
|
||||
"Dis-moi quelque chose sur l'assistant personnel Alexa",
|
||||
"Connais-tu quelque chose sur Cortana ?",
|
||||
"Dis-moi quelque chose sur l'assistant personnel Cortana",
|
||||
"Connais-tu quelque chose sur Siri ?",
|
||||
"Dis-moi quelque chose sur l'assistant personnel Siri",
|
||||
"Connais-tu quelque chose sur le Google Assistant ?",
|
||||
"Dis-moi quelque chose sur l'assistant personnel Google Assistant"
|
||||
"Connais-tu quelque chose sur @partnerAssistant ?",
|
||||
"Dis-moi quelque chose sur l'assistant personnel @partnerAssistant",
|
||||
"Dis-moi quelque chose à propos de @partnerAssistant",
|
||||
"Je veux en savoir plus au sujet de @partnerAssistant"
|
||||
]
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"partnerAssistant": {
|
||||
"options": {
|
||||
"Alexa": ["alexa"],
|
||||
"Cortana": ["cortana"],
|
||||
"Siri": ["siri"],
|
||||
"Google Assistant": ["google assistant"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"answers": {
|
||||
"alexa": [
|
||||
"Alexa est très sympa et Amazon lui enseigne pleins de choses. Elle est née en novembre 2014.",
|
||||
|
@ -6,17 +6,12 @@ import utils
|
||||
def run(string, entities):
|
||||
"""Leon tells you about other personal assistants"""
|
||||
|
||||
string = string.lower()
|
||||
partner = ''
|
||||
|
||||
assistants = [
|
||||
'alexa',
|
||||
'cortana',
|
||||
'siri',
|
||||
'google assistant'
|
||||
]
|
||||
|
||||
for assistant in assistants:
|
||||
if string.find(assistant) != -1:
|
||||
return utils.output('end', 'success', utils.translate(assistant.replace(' ', '_')))
|
||||
# Find entities
|
||||
for item in entities:
|
||||
if item['entity'] == 'partnerAssistant':
|
||||
partner = item['option'].lower()
|
||||
return utils.output('end', 'success', utils.translate(partner.replace(' ', '_')))
|
||||
|
||||
return utils.output('end', 'unknown', utils.translate('unknown'))
|
||||
|
@ -1,6 +1,6 @@
|
||||
import moment from 'moment-timezone'
|
||||
|
||||
import utterance_samples from '@/data/en.json' // eslint-disable-line camelcase
|
||||
import utterance_samples from '../../core/data/en/answers.json' // eslint-disable-line camelcase
|
||||
|
||||
jest.setTimeout(60000)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user