Skip to content

Commit

Permalink
refactor/common_query_speedup (#22)
Browse files Browse the repository at this point in the history
* refactor/common_query_speedup

* session support

* session support

* session support
  • Loading branch information
JarbasAl authored Jan 12, 2024
1 parent 97ae655 commit b1897cb
Showing 1 changed file with 98 additions and 49 deletions.
147 changes: 98 additions & 49 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@

import requests
import simplematch
from ovos_bus_client.session import Session, SessionManager
from ovos_classifiers.heuristics.keyword_extraction import HeuristicExtractor
from ovos_plugin_manager.templates.solvers import QuestionSolver
from ovos_utils import classproperty
from ovos_utils.gui import can_use_gui
from ovos_utils.intents import IntentBuilder
from ovos_utils.process_utils import RuntimeRequirements

from ovos_plugin_manager.templates.solvers import QuestionSolver
from ovos_workshop.decorators import intent_handler
from ovos_workshop.intents import IntentBuilder
from ovos_workshop.skills.common_query_skill import CommonQuerySkill, CQSMatchLevel


Expand Down Expand Up @@ -150,14 +152,13 @@ def get_spoken_answer(self, query, context=None):
query assured to be in self.default_lang
return a single sentence text response
"""
query, context, lang = self._tx_query(query, context)

# match an infobox field with some basic regexes
# (primitive intent parsing)
selected, key = DDGIntents.match(query, lang)
selected, key = DDGIntents.match(query, self.default_lang)

if key:
selected = self.extract_keyword(selected, lang)
selected = self.extract_keyword(selected, self.default_lang)
infobox = self.get_infobox(selected, context)[0] or {}
answer = infobox.get(key)
if answer:
Expand Down Expand Up @@ -199,11 +200,8 @@ def get_expanded_answer(self, query, context=None):

class DuckDuckGoSkill(CommonQuerySkill):
def initialize(self):
self.session_results = {}
self.duck = DuckDuckGoSolver()
# for usage in tell me more / follow up questions
self.idx = 0
self.results = []
self.image = None

@classproperty
def runtime_requirements(self):
Expand All @@ -221,67 +219,118 @@ def runtime_requirements(self):
@intent_handler("search_duck.intent")
def handle_search(self, message):
query = message.data["query"]
summary = self.ask_the_duck(query)

sess = SessionManager.get(message)
self.session_results[sess.session_id] = {
"query": query,
"results": [],
"idx": 0,
"lang": sess.lang,
"image": None,
}

summary = self.ask_the_duck(query, self.lang)
if summary:
self.speak_result()
self.speak_result(sess)
else:
self.speak_dialog("no_answer")

@intent_handler(IntentBuilder("DuckMore").require("More").
require("DuckKnows"))
def handle_tell_more(self, message):
""" Follow up query handler, "tell me more"."""
# query = message.data["DuckKnows"]
# data, related_queries = self.duck.get_infobox(query)
# TODO maybe do something with the infobox data ?
self.speak_result()
"""Follow up query handler, "tell me more".
If a "spoken_lines" entry exists in the active contexts
this can be triggered.
"""
sess = SessionManager.get(message)
self.speak_result(sess)

# common query
def CQS_match_query_phrase(self, utt):
summary = self.ask_the_duck(utt)
def CQS_match_query_phrase(self, phrase):
sess = SessionManager.get()
self.session_results[sess.session_id] = {
"query": phrase,
"results": [],
"idx": 0,
"lang": sess.lang,
"title": phrase,
"image": None
}
summary = self.ask_the_duck(sess)
if summary:
self.idx += 1 # spoken by common query
return (utt, CQSMatchLevel.GENERAL, summary,
{'query': utt,
'image': self.image,
self.log.info(f"DDG answer: {summary}")
return (phrase, CQSMatchLevel.GENERAL, summary,
{'query': phrase,
'answer': summary})

def CQS_action(self, phrase, data):
""" If selected show gui """
self.display_ddg(data["answer"], data["image"])
sess = SessionManager.get()
if sess in self.session_results:
self.display_wiki_entry()
self.display_ddg(sess)

# duck duck go api
def ask_the_duck(self, query):
# context for follow up questions
def ask_the_duck(self, sess):
if sess.lang.startswith("en"):
self.log.debug(f"skipping auto translation for DuckDuckGo, "
f"{sess.lang} is supported")
DuckDuckGoSolver.enable_tx = False
else:
self.log.info(f"enabling auto translation for DuckDuckGo, "
f"{sess.lang} is not supported internally")
DuckDuckGoSolver.enable_tx = True

query = self.session_results[sess.session_id]["query"]
self.set_context("DuckKnows", query)
self.idx = 0
self.results = self.duck.long_answer(query, lang=self.lang)
self.image = self.duck.get_image(query)
if self.results:
return self.results[0]["summary"]
results = self.duck.long_answer(query, lang=sess.lang)
self.session_results[sess.session_id]["results"] = results
return results[0]["summary"]

def display_ddg(self, summary=None, image=None):
def display_ddg(self, sess: Session):
if not can_use_gui(self.bus):
return
image = image or \
self.image or \
"https://github.com/JarbasSkills/skill-ddg/raw/master/ui/logo.png"
if image.startswith("/"):
image = "https://duckduckgo.com" + image
self.gui['summary'] = summary or ""
self.gui['imgLink'] = image
self.gui.show_page("DuckDelegate.qml", override_idle=60)

def speak_result(self):
if self.idx + 1 > len(self.results):
self.speak_dialog("thats all")
self.remove_context("DuckKnows")
self.idx = 0
if sess.session_id in self.session_results:
idx = self.session_results[sess.session_id]["idx"]
query = self.session_results[sess.session_id].get("query")
results = self.session_results[sess.session_id]["results"]
summary = results[idx]["summary"]
image = self.session_results[sess.session_id].get("image") or self.duck.get_image(query)
title = self.session_results[sess.session_id].get("title") or "DuckDuckGo"
image = image or "https://github.com/JarbasSkills/skill-ddg/raw/master/ui/logo.png"
if image.startswith("/"):
image = "https://duckduckgo.com" + image
self.gui['summary'] = summary or ""
self.gui['imgLink'] = image
self.gui.show_page("DuckDelegate", override_idle=60)

def speak_result(self, sess: Session):

if sess in self.session_results:
results = self.session_results[sess.session_id]["results"]
idx = self.session_results[sess.session_id]["idx"]
title = self.session_results[sess.session_id].get("title") or \
"DuckDuckGo"

if idx + 1 > len(self.results):
self.speak_dialog("thats all")
self.remove_context("DuckKnows")
self.session_results[sess.session_id]["idx"] = 0
else:
self.speak(results[idx]["summary"])
self.set_context("DuckKnows", "DuckDuckGo")
self.display_ddg(sess)
self.session_results[sess.session_id]["idx"] += 1
else:
self.display_ddg(self.results[self.idx]["summary"],
self.results[self.idx]["img"])
self.speak(self.results[self.idx]["summary"])
self.idx += 1
self.speak_dialog("thats all")

def stop(self):
self.gui.release()

def stop_session(self, sess):
if sess.session_id in self.session_results:
self.session_results.pop(sess.session_id)


if __name__ == "__main__":
Expand Down

0 comments on commit b1897cb

Please sign in to comment.