internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: MycroftAI/mycroft-core

Issue:
Cache Remote configuration for use if connection should fail
To provide the user with a more coherent experience even if the configuration loading should fail a local cache of the last downloaded configuration should be used. This will provide a configuration that is close to what the user expects, and as soon as a configuration update succeeds the newer settings will override the older.


Discussion:

Resolving patch:
diff --git a/mycroft/configuration/__init__.py b/mycroft/configuration/__init__.py
--- a/mycroft/configuration/__init__.py
+++ b/mycroft/configuration/__init__.py
@@ -91,7 +91,6 @@ def load(config=None, locations=None, keep_user_config=True):
         locations = ConfigurationLoader.init_locations(locations,
                                                        keep_user_config)
         ConfigurationLoader.validate(config, locations)
-
         for location in locations:
             config = ConfigurationLoader.__load(config, location)
 
@@ -135,6 +134,7 @@ class RemoteConfiguration(object):
     config in the [core] config section
     """
     IGNORED_SETTINGS = ["uuid", "@type", "active", "user", "device"]
+    WEB_CONFIG_CACHE = '/opt/mycroft/web_config_cache.json'
 
     @staticmethod
     def validate(config):
@@ -156,8 +156,11 @@ def load(config=None):
                 if location:
                     setting["location"] = location
                 RemoteConfiguration.__load(config, setting)
+                RemoteConfiguration.__store_cache(setting)
             except Exception as e:
                 LOG.warn("Failed to fetch remote configuration: %s" % repr(e))
+                RemoteConfiguration.__load_cache(config)
+
         else:
             LOG.debug("Remote configuration not activated.")
         return config
@@ -173,10 +176,35 @@ def __load(config, setting):
                     config[key] = config.get(key, {})
                     RemoteConfiguration.__load(config[key], v)
                 elif isinstance(v, list):
+                    if key not in config:
+                        config[key] = {}
                     RemoteConfiguration.__load_list(config[key], v)
                 else:
                     config[key] = v
 
+    @staticmethod
+    def __store_cache(setting):
+        """
+            Cache the received settings locally. The cache will be used if
+            the remote is unreachable to load settings that are as close
+            to the user's as possible
+        """
+        config = {}
+        # Remove server specific entries
+        RemoteConfiguration.__load(config, setting)
+        with open(RemoteConfiguration.WEB_CONFIG_CACHE, 'w') as f:
+            json.dump(config, f)
+
+    @staticmethod
+    def __load_cache(config):
+        """
+            Load cache from file
+        """
+        LOG.info("Using cached configuration if available")
+        ConfigurationLoader.load(config,
+                                 [RemoteConfiguration.WEB_CONFIG_CACHE],
+                                 False)
+
     @staticmethod
     def __load_list(config, values):
         for v in values:


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
setup_base.py uses deprecated __version__.py calls.
Setup_base.py by default tries to get the current version by importing `mycroft.__version`. However, this is no longer used. It should be updated to use the new versioning system.


Discussion:
Closed by #802 

Resolving patch:
diff --git a/mycroft/util/setup_base.py b/mycroft/util/setup_base.py
--- a/mycroft/util/setup_base.py
+++ b/mycroft/util/setup_base.py
@@ -36,8 +36,8 @@ def place_manifest(manifest_file):
 def get_version():
     version = None
     try:
-        import mycroft.__version__
-        version = mycroft.__version__.version
+        from mycroft.version import CORE_VERSION_STR
+        version = CORE_VERSION_STR
     except Exception as e:
         try:
             version = "dev-" + subprocess.check_output(


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
TTS debug output in cli



Discussion:

Resolving patch:
diff --git a/mycroft/client/text/main.py b/mycroft/client/text/main.py
--- a/mycroft/client/text/main.py
+++ b/mycroft/client/text/main.py
@@ -248,30 +248,45 @@ def rebuild_filtered_log():
 ##############################################################################
 # Capturing output from Mycroft
 
-def handle_speak(event):
-    global chat
+tts_threads = []
+
+
+def start_tts(utterance):
+    """
+    Begin speaking in another thread to redirect output
+    Otherwise, the CLI get's polluted with text to speech debug
+    """
     global tts
     mutex.acquire()
+
     if not bQuiet:
         ws.emit(Message("recognizer_loop:audio_output_start"))
     try:
-        utterance = event.data.get('utterance')
-        if bSimple:
-            print(">> " + utterance)
-        else:
-            chat.append(">> " + utterance)
-        draw_screen()
-        if not bQuiet:
-            if not tts:
-                tts = TTSFactory.create()
-                tts.init(ws)
-            tts.execute(utterance)
+        if not tts:
+            tts = TTSFactory.create()
+            tts.init(ws)
+        tts.execute(utterance)
     finally:
         mutex.release()
         if not bQuiet:
             ws.emit(Message("recognizer_loop:audio_output_end"))
 
 
+def handle_speak(event):
+    global chat
+    global tts_threads
+    utterance = event.data.get('utterance')
+    if bSimple:
+        print(">> " + utterance)
+    else:
+        chat.append(">> " + utterance)
+    draw_screen()
+    if not bQuiet:
+        t = Thread(start_tts, utterance)
+        t.start()
+        tts_threads.append(t)
+
+
 def connect():
     # Once the websocket has connected, just watch it for speak events
     ws.run_forever()
@@ -749,7 +764,7 @@ def main(stdscr):
                 # resizeterm() causes another curses.KEY_RESIZE, so
                 # we need to capture that to prevent a loop of resizes
                 c = scr.getch()
-            elif c == curses.KEY_BACKSPACE:
+            elif c == curses.KEY_BACKSPACE or c == 127:
                 # Backspace to erase a character in the utterance
                 line = line[:-1]
             elif curses.ascii.isascii(c):


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Mycroft doesn't starts if /etc/mycroft/mycroft.conf exists and has comments
In log.py there are these statements:

if isfile(SYSTEM_CONFIG):
    with open(SYSTEM_CONFIG) as f:
        config = json.load(f)
        log_level = config.get("log_level", "DEBUG")

note no filter of comments has been done using "load_commented_json".

Note: no pull request will be done, because could be the best solution is do not load any config here but use the common configuration procedure.


Discussion:
Thanks!
We do actually use that config file for system specific configuration such as platform detection in a Picroft image, so it has some purpose for us.
In a development setup, it would probably be best to use the user level mycroft.conf.
All of our JSON loading should use load_commented_json().  Thanks for pointing this out.

Resolving patch:
diff --git a/mycroft/util/log.py b/mycroft/util/log.py
--- a/mycroft/util/log.py
+++ b/mycroft/util/log.py
@@ -18,6 +18,7 @@
 import logging
 
 from os.path import isfile
+from mycroft.util.json_helper import load_commented_json
 
 SYSTEM_CONFIG = '/etc/mycroft/mycroft.conf'
 
@@ -26,9 +27,8 @@
 log_level = "DEBUG"
 
 if isfile(SYSTEM_CONFIG):
-    with open(SYSTEM_CONFIG) as f:
-        config = json.load(f)
-        log_level = config.get("log_level", "DEBUG")
+    config = load_commented_json(SYSTEM_CONFIG)
+    log_level = config.get("log_level", "DEBUG")
 
 FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
 logging.basicConfig(format=FORMAT, level=logging.getLevelName(log_level))


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Add remove_all_listeners to EventEmitter
I would like to be able to use this in some skills.


Discussion:

Resolving patch:
diff --git a/mycroft/messagebus/client/ws.py b/mycroft/messagebus/client/ws.py
--- a/mycroft/messagebus/client/ws.py
+++ b/mycroft/messagebus/client/ws.py
@@ -100,6 +100,17 @@ def once(self, event_name, func):
     def remove(self, event_name, func):
         self.emitter.remove_listener(event_name, func)
 
+    def remove_all_listeners(self, event_name):
+        '''
+            Remove all listeners connected to event_name.
+
+            Args:
+                event_name: event from which to remove listeners
+        '''
+        if event_name is None:
+            raise ValueError
+        self.emitter.remove_all_listeners(event_name)
+
     def run_forever(self):
         self.client.run_forever()
 


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Failing to load dialog and vocab should not be errors
Failure to load dialog files and vocab files are currently logged using the error log level. this should probably be debug or warnings since the ERROR text in the log confuses users.


Discussion:

Resolving patch:
diff --git a/mycroft/skills/core.py b/mycroft/skills/core.py
--- a/mycroft/skills/core.py
+++ b/mycroft/skills/core.py
@@ -306,7 +306,7 @@ def init_dialog(self, root_directory):
         if os.path.exists(dialog_dir):
             self.dialog_renderer = DialogLoader().load(dialog_dir)
         else:
-            logger.error('No dialog loaded, ' + dialog_dir + ' does not exist')
+            logger.debug('No dialog loaded, ' + dialog_dir + ' does not exist')
 
     def load_data_files(self, root_directory):
         self.init_dialog(root_directory)
@@ -319,7 +319,7 @@ def load_vocab_files(self, vocab_dir):
         if os.path.exists(vocab_dir):
             load_vocabulary(vocab_dir, self.emitter)
         else:
-            logger.error('No vocab loaded, ' + vocab_dir + ' does not exist')
+            logger.debug('No vocab loaded, ' + vocab_dir + ' does not exist')
 
     def load_regex_files(self, regex_dir):
         load_regex(regex_dir, self.emitter)


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
audio_end doesn't trigger in tts playback thread
I think a minor bug snuck into #892, Queue objects has no `len()` and the empty status needs to be checked with `.empty()`.

This means that the `...audio_output_end` message isn't sent.(and thus mic isn't unmuted, etc.)


Discussion:

Resolving patch:
diff --git a/mycroft/tts/__init__.py b/mycroft/tts/__init__.py
--- a/mycroft/tts/__init__.py
+++ b/mycroft/tts/__init__.py
@@ -18,7 +18,7 @@
 from abc import ABCMeta, abstractmethod
 from os.path import dirname, exists, isdir
 from threading import Thread
-from Queue import Queue
+from Queue import Queue, Empty
 from time import time, sleep
 import os
 import os.path
@@ -46,6 +46,7 @@ def __init__(self, queue):
         super(PlaybackThread, self).__init__()
         self.queue = queue
         self._terminated = False
+        self._processing_queue = False
 
     def init(self, tts):
         self.tts = tts
@@ -70,7 +71,10 @@ def run(self):
             try:
                 snd_type, data, visimes = self.queue.get(timeout=2)
                 self.blink(0.5)
-                self.tts.begin_audio()
+                if not self._processing_queue:
+                    self._processing_queue = True
+                    self.tts.begin_audio()
+
                 if snd_type == 'wav':
                     self.p = play_wav(data)
                 elif snd_type == 'mp3':
@@ -82,11 +86,18 @@ def run(self):
                 else:
                     self.p.communicate()
                 self.p.wait()
-                if len(self.queue) == 0:
+
+                if self.queue.empty():
                     self.tts.end_audio()
+                    self._processing_queue = False
                 self.blink(0.2)
-            except:
+            except Empty:
                 pass
+            except Exception, e:
+                LOGGER.exception(e)
+                if self._processing_queue:
+                    self.tts.end_audio()
+                    self._processing_queue = False
 
     def show_visimes(self, pairs):
         """


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Remove name parameter from MycroftSkill constructor
No reason to pass a name. Can use `self.__class__.__name__` instead. Do note, however, that for the reasonable future the constructor should still optionally accept the parameter as a means of backwards compatibility.


Discussion:

Resolving patch:
diff --git a/mycroft/skills/core.py b/mycroft/skills/core.py
--- a/mycroft/skills/core.py
+++ b/mycroft/skills/core.py
@@ -187,15 +187,16 @@ class MycroftSkill(object):
     Skills implementation.
     """
 
-    def __init__(self, name, emitter=None):
-        self.name = name
+    def __init__(self, name=None, emitter=None):
+        self.name = name or self.__class__.__name__
+
         self.bind(emitter)
         self.config_core = ConfigurationManager.get()
-        self.config = self.config_core.get(name)
+        self.config = self.config_core.get(self.name)
         self.dialog_renderer = None
-        self.file_system = FileSystemAccess(join('skills', name))
+        self.file_system = FileSystemAccess(join('skills', self.name))
         self.registered_intents = []
-        self.log = getLogger(name)
+        self.log = getLogger(self.name)
         self.reload_skill = True
         self.events = []
 


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
expect_response problems 
if `expect_response` is used to trigger Mycroft listening this happens before Mycroft has finished speaking.


Discussion:

Resolving patch:
diff --git a/mycroft/client/speech/main.py b/mycroft/client/speech/main.py
--- a/mycroft/client/speech/main.py
+++ b/mycroft/client/speech/main.py
@@ -96,6 +96,13 @@ def handle_multi_utterance_intent_failure(event):
     mute_and_speak("Sorry, I didn't catch that. Please rephrase your request.")
 
 
+def _trigger_expect_response(message):
+    """
+        Makes mycroft start listening on 'recognizer_loop:audio_output_end'
+    """
+    create_signal('startListening')
+
+
 def handle_speak(event):
     global _last_stop_signal
 
@@ -104,7 +111,9 @@ def handle_speak(event):
     create_signal("isSpeaking")
 
     utterance = event.data['utterance']
-    expect_response = event.data.get('expect_response', False)
+
+    if event.data.get('expect_response', False):
+        ws.once('recognizer_loop:audio_output_end', _trigger_expect_response)
 
     # This is a bit of a hack for Picroft.  The analog audio on a Pi blocks
     # for 30 seconds fairly often, so we don't want to break on periods
@@ -133,9 +142,6 @@ def handle_speak(event):
     # This check will clear the "signal"
     check_for_signal("isSpeaking")
 
-    if expect_response:
-        create_signal('startListening')
-
 
 def handle_sleep(event):
     loop.sleep()


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Audio service doesn't log audio service messages
Audio service logs all messages _except_ those relevant for the audio service.


Discussion:

Resolving patch:
diff --git a/mycroft/audio/main.py b/mycroft/audio/main.py
--- a/mycroft/audio/main.py
+++ b/mycroft/audio/main.py
@@ -413,8 +413,7 @@ def main():
     def echo(message):
         try:
             _message = json.loads(message)
-
-            if 'mycroft.audio.service' in _message.get('type'):
+            if 'mycroft.audio.service' not in _message.get('type'):
                 return
             message = json.dumps(_message)
         except:


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Import useful classes in mycroft package
This is open for discussion, but I think it is worth importing a few classes/functions in `mycroft/__init__.py` so that skills can do things like:
```Python
from mycroft import MycroftSkill  # vs. from mycroft.skills.core import MycroftSkil
class MySkill(MycroftSkill):
# ...
```

Or:
```Python
from mycroft import FallbackSkill, play_wav
class MediaFallback(FallbackSkill):
    def handle_fallback(self, message):
        # ...
        play_wav('my_song.wav')
        # ...


Discussion:
I think this is an excellent idea!

`Message` is another class that's dreadfully long to include if one wants to use:

currently
```python
from mycroft.messagebus.message import Message
```


Resolving patch:
diff --git a/mycroft/__init__.py b/mycroft/__init__.py
--- a/mycroft/__init__.py
+++ b/mycroft/__init__.py
@@ -1,3 +1,9 @@
+from mycroft.api import Api
+from mycroft.skills.core import MycroftSkill, FallbackSkill, \
+    intent_handler, intent_file_handler
+from mycroft.skills.context import adds_context, removes_context
+from mycroft.messagebus.message import Message
+
 from os.path import abspath, dirname, join
 
 __author__ = 'seanfitz'
diff --git a/mycroft/util/__init__.py b/mycroft/util/__init__.py
--- a/mycroft/util/__init__.py
+++ b/mycroft/util/__init__.py
@@ -15,6 +15,12 @@
 # You should have received a copy of the GNU General Public License
 # along with Mycroft Core.  If not, see <http://www.gnu.org/licenses/>.
 
+# Officially exported methods from this file:
+# play_wav, play_mp3, get_cache_directory,
+# resolve_resource_file, wait_while_speaking
+from mycroft.util.log import getLogger
+from mycroft.util.parse import extract_datetime, extractnumber, normalize
+from mycroft.util.format import nice_number, convert_number
 
 import socket
 import subprocess
@@ -26,7 +32,6 @@
 import time
 from stat import S_ISREG, ST_MTIME, ST_MODE, ST_SIZE
 import psutil
-from mycroft.util.log import getLogger
 from mycroft.util.signal import *
 import mycroft.configuration
 import mycroft.audio


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
UnicodeDecodeError with accents in dialog files in other languages
Hi, I'm french and we have a lot of accents there !

Should be smart to add utf-8 support while opening dialog files ?
Using codecs module works fine for me in `mycroft/dialog/__init__.py` line 47:

`import codecs`
`with codecs.open(filename, 'r', 'utf-8') as f:`


Discussion:
For future proofing maybe `io.open()` should be used instead?
Yes you're right indeed, `io.open()` is a better way (the default python3 way).
Played around with this a bit and found a couple of more internationalization errors. PR coming soonish.

Mycroft's french is terrible by the way :)

Resolving patch:
diff --git a/mycroft/client/speech/recognizer/pocketsphinx_recognizer.py b/mycroft/client/speech/recognizer/pocketsphinx_recognizer.py
--- a/mycroft/client/speech/recognizer/pocketsphinx_recognizer.py
+++ b/mycroft/client/speech/recognizer/pocketsphinx_recognizer.py
@@ -20,7 +20,7 @@
 import tempfile
 import time
 
-from os.path import join, dirname, abspath
+from os.path import join, dirname, abspath, exists
 from pocketsphinx import Decoder
 
 from mycroft.client.speech.recognizer.local_recognizer import LocalRecognizer
@@ -52,7 +52,12 @@ def create_dict(self, key_phrase, phonemes):
 
     def create_config(self, dict_name):
         config = Decoder.default_config()
-        config.set_string('-hmm', join(BASEDIR, 'model', self.lang, 'hmm'))
+        model_file = join(BASEDIR, 'model', self.lang, 'hmm')
+        if not exists(model_file):
+            LOG.error('PocketSphinx model not found for {}', self.lang)
+            model_file = join(BASEDIR, 'model', 'en-us', 'hmm')
+
+        config.set_string('-hmm', model_file)
         config.set_string('-dict', dict_name)
         config.set_string('-keyphrase', self.key_phrase)
         config.set_float('-kws_threshold', float(self.threshold))
diff --git a/mycroft/dialog/__init__.py b/mycroft/dialog/__init__.py
--- a/mycroft/dialog/__init__.py
+++ b/mycroft/dialog/__init__.py
@@ -17,6 +17,7 @@
 
 
 import pystache
+from io import open
 import os
 import random
 from mycroft.util import log, resolve_resource_file
diff --git a/mycroft/skills/time_rules.py b/mycroft/skills/time_rules.py
--- a/mycroft/skills/time_rules.py
+++ b/mycroft/skills/time_rules.py
@@ -167,5 +167,5 @@ def fill_week_days(self, group, days):
 def create(lang):
     clazz = KEY_MAP.get(lang)
     if not clazz:
-        clazz = TimeRulesEnUs()
+        clazz = TimeRulesEnUs
     return clazz()


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
Calling the pause() function does not pause the playback
This [pause() function](https://github.com/MycroftAI/mycroft-core/blob/a9d627c979b98053719200c6084f3b31a9a97c62/mycroft/skills/audioservice.py#L83) does not have the desired effect of pausing the playback. 
`self.emitter.emit(Message('mycroft.sudio.service.stop'))`
This stops the playback, but the Audioservice does not expose a stop function. I could make the commit to add the stop() function if agreed upon.


Discussion:
The pause method is not supported by all backends, for example mpg123 doesn't support it but if the vlc backend is selected as default it will work. (The vlc backend should be set as default, it's tested well enough now)

Adding stop to the interface is a good idea, I'd be happy to accept a PR with this :)

The stop signal is currently tied to the the global stop (writing `stop` in cli or pressing the button on top of the mark-1), a message bus `mycroft.audio.service.stop` exists to handle it so it would be good to have that added to the interface.

Resolving patch:
diff --git a/mycroft/skills/audioservice.py b/mycroft/skills/audioservice.py
--- a/mycroft/skills/audioservice.py
+++ b/mycroft/skills/audioservice.py
@@ -72,6 +72,10 @@ def play(self, tracks=[], utterance=''):
                                   data={'tracks': tracks,
                                         'utterance': utterance}))
 
+    def stop(self):
+        """ Stop the track. """
+        self.emitter.emit(Message('mycroft.audio.service.stop'))
+
     def next(self):
         """ Change to next track. """
         self.emitter.emit(Message('mycroft.audio.service.next'))


Test patch:
Repository: MycroftAI/mycroft-core

Issue:
skill config parameter could be more user friendly
Currently the skill config parameter is defaulted to `None` if the skill has no entry in the configuration. This makes configuration checks a bit more complicated than necessary since the skill creator always need to check that 

```
if self.config is not None:
    val = self.config.get('val')
```

or similar.

Defaulting `self.config` to an empty dict `{}` would simplify this a bit.


Discussion:
Has this been fixed? I'm looking at contributor friendly issues, but I can't seem to find the piece of code that you're referring to.
Hi, sorry for the long delay.

The issue is referring to https://github.com/MycroftAI/mycroft-core/blob/dev/mycroft/skills/core.py#L213

The configs are initiated to the config if existing or `None` if missing. This could be changed to an empty dict `{}` if missing so the skill creator doesn't need to check if the member is set or not before accessing
```python
if self.config:
    my_var = self.config.get('my_var')
```

could be simplified if the skill creator can trust that the config member is always a dict.

```python
    my_var = self.config.get('my_var')
```

Resolving patch:
diff --git a/mycroft/skills/core.py b/mycroft/skills/core.py
--- a/mycroft/skills/core.py
+++ b/mycroft/skills/core.py
@@ -210,7 +210,7 @@ def __init__(self, name=None, emitter=None):
 
         self.bind(emitter)
         self.config_core = Configuration.get()
-        self.config = self.config_core.get(self.name)
+        self.config = self.config_core.get(self.name) or {}
         self.dialog_renderer = None
         self.vocab_dir = None
         self.root_dir = None


Test patch: