forked from forslund/fallback-aiml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__init__.py
136 lines (117 loc) · 4.8 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# Copyright 2016 Mycroft AI, Inc.
#
# This file is part of Mycroft Core.
#
# Mycroft Core is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mycroft Core is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mycroft Core. If not, see <http://www.gnu.org/licenses/>.
import aiml
import os
from os import listdir, remove as remove_file
from os.path import dirname, isfile
from mycroft.api import DeviceApi
from mycroft.skills.core import FallbackSkill, intent_handler
from adapt.intent import IntentBuilder
from mycroft.util.log import LOG
class AimlFallback(FallbackSkill):
def __init__(self):
super(AimlFallback, self).__init__(name='AimlFallback')
self.kernel = aiml.Kernel()
self.aiml_path = os.path.join(dirname(__file__), "aiml")
self.brain_path = os.path.join(self.file_system.path,
"bot_brain.brn")
# reloading skills will also reset this 'timer', so ideally it should
# not be too high
self.line_count = 1
self.save_loop_threshold = int(self.settings.get('save_loop_threshold',
4))
self.brain_loaded = False
def initialize(self):
self.register_fallback(self.handle_fallback, 90)
return
def load_brain(self):
LOG.info('Loading Brain')
if isfile(self.brain_path):
self.kernel.bootstrap(brainFile=self.brain_path)
else:
aimls = listdir(self.aiml_path)
for aiml in aimls:
self.kernel.learn(os.path.join(self.aiml_path, aiml))
self.kernel.saveBrain(self.brain_path)
try:
device = DeviceApi().get()
except Exception:
device = {
"name": "Mycroft",
"type": "AI"
}
self.kernel.setBotPredicate("name", device["name"])
self.kernel.setBotPredicate("species", device["type"])
self.kernel.setBotPredicate("genus", "Mycroft")
self.kernel.setBotPredicate("family", "virtual personal assistant")
self.kernel.setBotPredicate("order", "artificial intelligence")
self.kernel.setBotPredicate("class", "computer program")
self.kernel.setBotPredicate("kingdom", "machine")
self.kernel.setBotPredicate("hometown", "127.0.0.1")
self.kernel.setBotPredicate("botmaster", "master")
self.kernel.setBotPredicate("master", "the community")
# IDEA: extract age from
# https://api.github.com/repos/MycroftAI/mycroft-core created_at date
self.kernel.setBotPredicate("age", "2")
self.brain_loaded = True
return
@intent_handler(IntentBuilder("ResetMemoryIntent").require("Reset")
.require("Memory"))
def handle_reset_brain(self, message):
LOG.debug('Deleting brain file')
# delete the brain file and reset memory
self.speak_dialog("reset.memory")
remove_file(self.brain_path)
self.soft_reset_brain()
return
def ask_brain(self, utterance):
response = self.kernel.respond(utterance)
# make a security copy once in a while
if (self.line_count % self.save_loop_threshold) == 0:
self.kernel.saveBrain(self.brain_path)
self.line_count += 1
return response
def soft_reset_brain(self):
# Only reset the active kernel memory
self.kernel.resetBrain()
self.brain_loaded = False
return
def handle_fallback(self, message):
if self.settings.get("enabled"):
if not self.brain_loaded:
self.load_brain()
utterance = message.data.get("utterance")
answer = self.ask_brain(utterance)
if answer != "":
asked_question = False
if answer.endswith("?"):
asked_question = True
self.speak(answer, expect_response=asked_question)
return True
if self.brain_loaded:
self.soft_reset_brain()
return False
def shutdown(self):
if self.brain_loaded:
self.kernel.saveBrain(self.brain_path)
self.kernel.resetBrain() # Manual remove
self.remove_fallback(self.handle_fallback)
super(AimlFallback, self).shutdown()
def stop(self):
pass
def create_skill():
return AimlFallback()