First implementation of questions management
This commit is contained in:
@@ -4,6 +4,7 @@ import time
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.services.SheerkaExecute import NO_MATCH
|
||||
from core.sheerka.services.SheerkaShortTermMemory import SheerkaShortTermMemory
|
||||
from core.sheerka_logger import get_logger
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
@@ -11,11 +12,13 @@ DEBUG_TAB_SIZE = 4
|
||||
|
||||
PROPERTIES_TO_SERIALIZE = ("_id",
|
||||
"_bag",
|
||||
"_children",
|
||||
"_start",
|
||||
"_stop",
|
||||
"who",
|
||||
"action",
|
||||
"action_context",
|
||||
"desc",
|
||||
"children",
|
||||
"inputs",
|
||||
"values",
|
||||
"obj",
|
||||
@@ -46,16 +49,20 @@ class ExecutionContext:
|
||||
desc: str = None,
|
||||
logger=None,
|
||||
global_hints=None,
|
||||
global_errors=None,
|
||||
errors=None,
|
||||
**kwargs):
|
||||
|
||||
self._parent = None
|
||||
self._id = ExecutionContext.get_id(event.get_digest()) if event else None
|
||||
self._parent = None
|
||||
self._children = []
|
||||
self._tab = ""
|
||||
self._bag = {} # context variables
|
||||
self._start = 0 # when the execution starts (to measure elapsed time)
|
||||
self._stop = 0 # when the execution stops (to measure elapses time)
|
||||
self._logger = logger
|
||||
self._format_instructions = None # how to print the execution context
|
||||
self._stat_log = get_logger("stats")
|
||||
self._show_stats = False
|
||||
|
||||
self.who = who # who is asking
|
||||
self.event = event # what was the (original) trigger
|
||||
@@ -63,26 +70,24 @@ class ExecutionContext:
|
||||
self.action = action
|
||||
self.action_context = action_context
|
||||
self.desc = desc # human description of what is going on
|
||||
self.children = []
|
||||
self.preprocess = None
|
||||
self.logger = logger
|
||||
self.local_hints = set()
|
||||
self.stm = False # True if the context has short term memory entries
|
||||
|
||||
self.private_hints = set()
|
||||
self.protected_hints = set()
|
||||
self.global_hints = set() if global_hints is None else global_hints
|
||||
self.global_errors = [] if global_errors is None else global_errors
|
||||
self.errors = [] if errors is None else errors # error are global
|
||||
|
||||
self.inputs = {} # what was the parameters of the execution context
|
||||
self.inputs = {} # what were the parameters of the execution context
|
||||
self.values = {} # what was produced by the execution context
|
||||
|
||||
self.obj = kwargs.pop("obj", None) # current obj we are working on
|
||||
|
||||
self.concepts = kwargs.pop("concepts", {}) # known concepts specific to this context
|
||||
|
||||
# update the other elements
|
||||
for k, v in kwargs.items():
|
||||
self._bag[k] = v
|
||||
|
||||
self.stat_log = get_logger("stats")
|
||||
self.show_stats = False
|
||||
|
||||
@property
|
||||
def elapsed(self):
|
||||
if self._start == 0:
|
||||
@@ -96,10 +101,22 @@ class ExecutionContext:
|
||||
dt = nano_sec / 1e6
|
||||
return f"{dt} ms" if dt < 1000 else f"{dt / 1000} s"
|
||||
|
||||
@property
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def achildren(self):
|
||||
"""
|
||||
I prefixed with an 'a' to make it appear on the top when debugging
|
||||
:return:
|
||||
"""
|
||||
return self._children
|
||||
|
||||
def __getattr__(self, item):
|
||||
if item in self._bag:
|
||||
return self._bag[item]
|
||||
@@ -112,9 +129,12 @@ class ExecutionContext:
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.stm:
|
||||
self.sheerka.services[SheerkaShortTermMemory.NAME].remove_context(self)
|
||||
|
||||
self._stop = time.time_ns()
|
||||
if self.show_stats:
|
||||
self.stat_log.debug(f"[{self._id:2}]" + self._tab + "Execution time: " + self.elapsed_str)
|
||||
if self._show_stats:
|
||||
self._stat_log.debug(f"[{self._id:2}]" + self._tab + "Execution time: " + self.elapsed_str)
|
||||
|
||||
def __repr__(self):
|
||||
msg = f"ExecutionContext(who={self.who}, id={self._id}, action={self.action}, context={self.action_context}"
|
||||
@@ -136,7 +156,7 @@ class ExecutionContext:
|
||||
return False
|
||||
|
||||
for prop in PROPERTIES_TO_SERIALIZE:
|
||||
if prop == "who":
|
||||
if prop in ("who", "action", "action_context"):
|
||||
value = str(getattr(self, prop))
|
||||
other_value = str(getattr(other, prop))
|
||||
else:
|
||||
@@ -150,7 +170,7 @@ class ExecutionContext:
|
||||
|
||||
def push(self, action: BuiltinConcepts, action_context, who=None, desc=None, logger=None, **kwargs):
|
||||
who = who or self.who
|
||||
logger = logger or self.logger
|
||||
logger = logger or self._logger
|
||||
_kwargs = {"obj": self.obj, "concepts": self.concepts}
|
||||
_kwargs.update(self._bag)
|
||||
_kwargs.update(kwargs)
|
||||
@@ -163,14 +183,14 @@ class ExecutionContext:
|
||||
desc,
|
||||
logger,
|
||||
self.global_hints,
|
||||
self.global_errors,
|
||||
self.errors,
|
||||
**_kwargs)
|
||||
new._parent = self
|
||||
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
||||
new.preprocess = self.preprocess
|
||||
new.local_hints.update(self.local_hints)
|
||||
new.protected_hints.update(self.protected_hints)
|
||||
|
||||
self.children.append(new)
|
||||
self._children.append(new)
|
||||
return new
|
||||
|
||||
def add_preprocess(self, name, **kwargs):
|
||||
@@ -194,6 +214,23 @@ class ExecutionContext:
|
||||
self.values[k] = v
|
||||
return self
|
||||
|
||||
def add_to_short_term_memory(self, key, concept):
|
||||
"""
|
||||
Add a concept to the short term memory (relative to the current execution context)
|
||||
:param key:
|
||||
:param concept:
|
||||
:return:
|
||||
"""
|
||||
self.sheerka.add_to_short_term_memory(self, key, concept)
|
||||
|
||||
def get_from_short_term_memory(self, key):
|
||||
"""
|
||||
|
||||
:param key:
|
||||
:return:
|
||||
"""
|
||||
return self.sheerka.get_from_short_term_memory(self, key)
|
||||
|
||||
def get_concept(self, key):
|
||||
# search in obj
|
||||
if isinstance(self.obj, Concept):
|
||||
@@ -234,44 +271,43 @@ class ExecutionContext:
|
||||
return self.sheerka.new(key, **kwargs)
|
||||
|
||||
def log_new(self):
|
||||
if self.logger and not self.logger.disabled:
|
||||
self.logger.debug(f"[{self._id:2}]" + self._tab + str(self))
|
||||
self.show_stats = True
|
||||
if self._logger and not self._logger.disabled:
|
||||
self._logger.debug(f"[{self._id:2}]" + self._tab + str(self))
|
||||
self._show_stats = True
|
||||
|
||||
def log(self, message, who=None):
|
||||
if self.logger and not self.logger.disabled:
|
||||
self.logger.debug(f"[{self._id:2}]" + self._tab + (f"[{who}] " if who else "") + str(message))
|
||||
if self._logger and not self._logger.disabled:
|
||||
self._logger.debug(f"[{self._id:2}]" + self._tab + (f"[{who}] " if who else "") + str(message))
|
||||
|
||||
def log_error(self, message, who=None, exc=None):
|
||||
self.global_errors.append(exc or message)
|
||||
if self.logger and not self.logger.disabled:
|
||||
self.logger.exception(f"[{self._id:2}]" + self._tab + (f"[{who}] " if who else "") + str(message))
|
||||
self.errors.append(exc or message)
|
||||
if self._logger and not self._logger.disabled:
|
||||
self._logger.exception(f"[{self._id:2}]" + self._tab + (f"[{who}] " if who else "") + str(message))
|
||||
|
||||
def log_result(self, return_values):
|
||||
if not self.logger or not self.logger.isEnabledFor(logging.DEBUG):
|
||||
if not self._logger or not self._logger.isEnabledFor(logging.DEBUG):
|
||||
return
|
||||
|
||||
if len(return_values) == 0:
|
||||
self.logger.debug(self._tab + "No return value")
|
||||
self._logger.debug(self._tab + "No return value")
|
||||
|
||||
for r in return_values:
|
||||
to_str = self.return_value_to_str(r)
|
||||
self.logger.debug(f"[{self._id:2}]" + self._tab + "-> " + to_str)
|
||||
self._logger.debug(f"[{self._id:2}]" + self._tab + "-> " + to_str)
|
||||
|
||||
def get_parent(self):
|
||||
return self._parent
|
||||
|
||||
def in_context(self, concept_key):
|
||||
if concept_key in self.local_hints:
|
||||
return True
|
||||
|
||||
if concept_key in self.global_hints:
|
||||
return True
|
||||
|
||||
return False
|
||||
return concept_key in self.protected_hints or \
|
||||
concept_key in self.global_hints or \
|
||||
concept_key in self.private_hints
|
||||
|
||||
def in_current_context(self, concept_key):
|
||||
return concept_key in self.local_hints
|
||||
return concept_key in self.protected_hints or concept_key in self.private_hints
|
||||
|
||||
def in_private_context(self, concept_key):
|
||||
return concept_key in self.private_hints
|
||||
|
||||
@staticmethod
|
||||
def _is_return_value(obj):
|
||||
@@ -336,7 +372,7 @@ class ExecutionContext:
|
||||
bag["bag." + k] = v
|
||||
for prop in ("id", "who", "action", "desc", "obj", "inputs", "values", "concepts"):
|
||||
bag[prop] = getattr(self, prop)
|
||||
bag["action"] = self.action_context
|
||||
bag["context"] = self.action_context
|
||||
for prop in ("desc", "obj", "inputs", "values", "concepts"):
|
||||
bag[prop] = getattr(self, prop)
|
||||
bag["status"] = self.get_status()
|
||||
|
||||
Reference in New Issue
Block a user