diff --git a/hugvey/speech/google.py b/hugvey/speech/google.py index b69e8fd..41f6091 100644 --- a/hugvey/speech/google.py +++ b/hugvey/speech/google.py @@ -19,6 +19,7 @@ import uuid from hugvey.communication import LOG_BS import audioop import gc +import time mainLogger = logging.getLogger("hugvey") logger = mainLogger.getChild("google") @@ -198,6 +199,17 @@ class GoogleVoiceClient(object): except Exception as e: if "305" in str(e): self.logger.warning(f"Long Google Voice: {e}") + elif "TRANSIENT_FAILURE" in str(e): + self.logger.critical(f"Crashed Google Voice: {e}") + time.sleep(.3) + self.logger.critical(f"Reload config, in an attempt/guess to fix it") + config = types.RecognitionConfig( + encoding=enums.RecognitionConfig.AudioEncoding.LINEAR16, + sample_rate_hertz=self.src_rate, + language_code=self.getOfficialLangCode()) + self.streaming_config = types.StreamingRecognitionConfig( + config=config, + interim_results=True) else: self.logger.critical(f"Crashed Google Voice: {e}") diff --git a/hugvey/story.py b/hugvey/story.py index e011b17..d94c369 100644 --- a/hugvey/story.py +++ b/hugvey/story.py @@ -278,7 +278,9 @@ class Reply(object): self.utterances.append(utterance) def getText(self) -> str: - return ". ".join([u.text for u in self.utterances]).strip() + # for some reason utterances are sometimes empty.Strip these out + utterances = filter(None, [u.text.strip() for u in self.utterances]) + return ". ".join(utterances).strip() def getActiveUtterance(self, currentTime) -> Utterance: """ @@ -760,18 +762,24 @@ class Diversion(object): # story.logger.warn(f"Block diversion {self.id} because of hit message {self.params['notAfterMsgId']}") self.disabled = True # never run it and allow following timeouts/no_responses to run return False - - r = await self.method(story, - direction.msgFrom if direction else None, - direction.msgTo if direction else None, - direction if direction else None) - if r: - if self.type != 'repeat' and self.type !='interrupt': - # repeat diversion should be usable infinte times - self.hasHit = True + try: + r = await self.method(story, + direction.msgFrom if direction else None, + direction.msgTo if direction else None, + direction if direction else None) + if r: + if self.type != 'repeat' and self.type !='interrupt': + # repeat diversion should be usable infinte times + self.hasHit = True + + story.addToLog(self) + story.hugvey.eventLogger.info(f"diverge {self.id}") - story.addToLog(self) - story.hugvey.eventLogger.info(f"diverge {self.id}") + except Exception as e: + story.logger.critical("Exception when attempting diversion") + story.logger.exception(e) + return False + return r def createReturnDirectionsTo(self, story, startMsg, returnMsg, originalDirection = None, inheritTiming = True, timeoutDuration = .5, replyContainsDurations = None): @@ -818,6 +826,10 @@ class Diversion(object): usedReturnMessage = returnMsg if msg.generatedDirectionsJumpToChapter: usedReturnMessage = story.getNextChapterForMsg(returnMsg, canIncludeSelf=True) + + if not usedReturnMessage: + # in case of a diversion in the last bit of the story, it can be there there is no return message. + raise Exception(f"No return message found for {msg.id}") direction = Direction(f"{self.id}-{i}-{self.counter}", msg, usedReturnMessage) data = json.loads(f""" @@ -1562,6 +1574,11 @@ class Story(object): return if e['event'] == 'speech': + # TODO if transcript is empty, ignore (happened sometimes in french) + if len(e['transcript'].strip()) < 1: + self.logger.warning(f'ignore empty transcription {e}') + continue + # participants speaks, reset counter self.stats['consecutiveSilentTimeouts'] = 0 @@ -1599,7 +1616,7 @@ class Story(object): else: utterance.setText(e['transcript'], now) - self.hugvey.eventLogger.info("speaking: content {} \"{}\"".format(id(utterance), e['transcript'])) + self.hugvey.eventLogger.debug("speaking: content {} \"{}\"".format(id(utterance), e['transcript'])) if not self.timer.hasMark('first_speech'): self.timer.setMark('first_speech') self.timer.setMark('last_speech')