First implementation of Debugger for SyaNodeParser
This commit is contained in:
@@ -5,18 +5,13 @@ import time
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts, ParserResultConcept
|
||||
from core.concept import Concept, get_concept_attrs
|
||||
from core.global_symbols import CONTEXT_DISPOSED
|
||||
from core.global_symbols import EVENT_CONTEXT_DISPOSED
|
||||
from core.sheerka.services.SheerkaExecute import NO_MATCH
|
||||
from core.sheerka.services.SheerkaMemory import SheerkaMemory
|
||||
from core.utils import CONSOLE_COLORS_MAP as CCM
|
||||
from core.utils import CONSOLE_COLORS_MAP as CCM, CONSOLE_COLUMNS
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
try:
|
||||
rows, columns = os.popen('stty size', 'r').read().split()
|
||||
except ValueError:
|
||||
rows, columns = 50, 80
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=2, width=columns)
|
||||
pp = pprint.PrettyPrinter(indent=2, width=CONSOLE_COLUMNS)
|
||||
|
||||
DEBUG_TAB_SIZE = 4
|
||||
|
||||
@@ -134,7 +129,7 @@ class ExecutionContext:
|
||||
return
|
||||
|
||||
if self.stm:
|
||||
self.sheerka.publish(self, CONTEXT_DISPOSED)
|
||||
self.sheerka.publish(self, EVENT_CONTEXT_DISPOSED)
|
||||
|
||||
self._stop = time.time_ns()
|
||||
|
||||
@@ -207,7 +202,7 @@ class ExecutionContext:
|
||||
def activate_push(self):
|
||||
if self._push:
|
||||
if self._push.stm:
|
||||
self.sheerka.publish(self._push, CONTEXT_DISPOSED)
|
||||
self.sheerka.publish(self._push, EVENT_CONTEXT_DISPOSED)
|
||||
self._push._stop = time.time_ns()
|
||||
|
||||
self._push = None
|
||||
|
||||
+11
-53
@@ -14,9 +14,11 @@ from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConc
|
||||
UnknownConcept, AllBuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts, NotInit, get_concept_attrs
|
||||
from core.error import ErrorObj
|
||||
from core.global_symbols import EVENT_USER_INPUT_EVALUATED
|
||||
from core.profiling import profile
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from core.sheerka_logger import console_handler
|
||||
from core.simple_debug import my_debug
|
||||
from core.tokenizer import Token, TokenKind
|
||||
from printer.SheerkaPrinter import SheerkaPrinter
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||
@@ -81,15 +83,6 @@ class Sheerka(Concept):
|
||||
self.return_value_concept_id = None
|
||||
self.error_concept_id = None
|
||||
|
||||
# a concept can be instantiated
|
||||
# ex: File is a concept, but File('foo.txt') is an instance
|
||||
# TODO: manage contexts
|
||||
self.instances = []
|
||||
|
||||
# List of the known rules by the system
|
||||
# ex: hello => say('hello')
|
||||
self.rules = []
|
||||
|
||||
self.sdp: SheerkaDataProvider = None
|
||||
self.cache_manager = CacheManager(cache_only)
|
||||
|
||||
@@ -105,10 +98,11 @@ class Sheerka(Concept):
|
||||
self.printer_handler = SheerkaPrinter(self)
|
||||
|
||||
self.during_restore = False
|
||||
self.during_initialisation = False
|
||||
self._builtins_classes_cache = None
|
||||
|
||||
self.save_execution_context = True
|
||||
self.enable_process_return_values = False
|
||||
self.enable_process_return_values = True
|
||||
|
||||
self.methods_with_context = {"test_using_context"} # only the names, the method is defined in sheerka_methods
|
||||
self.sheerka_methods = {
|
||||
@@ -120,10 +114,6 @@ class Sheerka(Concept):
|
||||
|
||||
self.locals = {}
|
||||
|
||||
self.last_executions = []
|
||||
self.last_return_values = []
|
||||
self.execution_count = 0
|
||||
|
||||
@property
|
||||
def resolved_concepts_by_first_keyword(self):
|
||||
"""
|
||||
@@ -196,6 +186,7 @@ class Sheerka(Concept):
|
||||
self.enable_process_return_values = enable_process_return_values
|
||||
|
||||
try:
|
||||
self.during_initialisation = True
|
||||
from sheerkapickle.sheerka_handlers import initialize_pickle_handlers
|
||||
initialize_pickle_handlers()
|
||||
|
||||
@@ -235,6 +226,9 @@ class Sheerka(Concept):
|
||||
except IOError as e:
|
||||
res = ReturnValueConcept(self, False, self.get(BuiltinConcepts.ERROR), e)
|
||||
|
||||
finally:
|
||||
self.during_initialisation = False
|
||||
|
||||
return res
|
||||
|
||||
def initialize_caching(self):
|
||||
@@ -445,6 +439,7 @@ class Sheerka(Concept):
|
||||
:return:
|
||||
"""
|
||||
# self.log.debug(f"Processing user input '{text}', {user_name=}.")
|
||||
my_debug(f"****************** Processing user input '{text}', {user_name=}.***********************************")
|
||||
event = Event(text, user_name)
|
||||
self.sdp.save_event(event)
|
||||
|
||||
@@ -456,6 +451,7 @@ class Sheerka(Concept):
|
||||
desc=f"Evaluating '{text}'") as execution_context:
|
||||
|
||||
user_input = self.ret(self.name, True, self.new(BuiltinConcepts.USER_INPUT, body=text, user_name=user_name))
|
||||
execution_context.add_inputs(user_input=user_input)
|
||||
|
||||
# TODO. Must be a context hint, not a return value
|
||||
reduce_requested = self.ret(self.name, True, self.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
@@ -466,32 +462,12 @@ class Sheerka(Concept):
|
||||
if self.cache_manager.is_dirty:
|
||||
self.cache_manager.commit(execution_context)
|
||||
|
||||
# exec_count = ExecutionContext.ids[execution_context.event.get_digest()]
|
||||
# print("Execution Context Count:", exec_count)
|
||||
if self.save_execution_context:
|
||||
try:
|
||||
# if exec_count > 3400:
|
||||
# print("Saving result. digest=", execution_context.event.get_digest())
|
||||
self.sdp.save_result(execution_context)
|
||||
except Exception as ex:
|
||||
print(f"Failed to save execution context. Reason: {ex}")
|
||||
pass
|
||||
# self.log.error(f"Failed to save execution context. Reason: {ex}")
|
||||
self.publish(execution_context, EVENT_USER_INPUT_EVALUATED)
|
||||
|
||||
# Do not save execution contexts from process_return_values
|
||||
if self.enable_process_return_values:
|
||||
self.process_return_values(execution_context, ret)
|
||||
|
||||
self.execution_count += 1
|
||||
self._last_execution = execution_context
|
||||
if len(self.last_executions) == self.MAX_EXECUTION_HISTORY:
|
||||
del self.last_executions[0]
|
||||
self.last_executions.append(execution_context)
|
||||
|
||||
if len(self.last_return_values) == self.MAX_RETURN_VALUES_HISTORY:
|
||||
del self.last_return_values[0]
|
||||
self.last_return_values.append(ret)
|
||||
|
||||
return ret
|
||||
|
||||
def print(self, result, instructions=None):
|
||||
@@ -887,24 +863,6 @@ class Sheerka(Concept):
|
||||
|
||||
return self.parsers_prefix + name
|
||||
|
||||
# def concepts(self):
|
||||
# """
|
||||
# List of all known concepts (look up in sdp)
|
||||
# :return:
|
||||
# """
|
||||
# res = []
|
||||
# lst = self.sdp.list(self.CONCEPTS_BY_ID_ENTRY)
|
||||
# for item in lst:
|
||||
# if isinstance(item, list):
|
||||
# res.extend(item)
|
||||
# else:
|
||||
# res.append(item)
|
||||
#
|
||||
# return sorted(res, key=lambda i: int(i.id))
|
||||
|
||||
def get_last_execution(self):
|
||||
return self._last_execution
|
||||
|
||||
def test(self):
|
||||
return f"I have access to Sheerka !"
|
||||
|
||||
|
||||
@@ -24,9 +24,6 @@ class SheerkaAdmin(BaseService):
|
||||
self.sheerka.bind_service_method(self.restore, True)
|
||||
self.sheerka.bind_service_method(self.concepts, False)
|
||||
self.sheerka.bind_service_method(self.desc, False)
|
||||
self.sheerka.bind_service_method(self.last_created_concept, False)
|
||||
self.sheerka.bind_service_method(self.last_ret, False)
|
||||
self.sheerka.bind_service_method(self.last_error_ret, False)
|
||||
self.sheerka.bind_service_method(self.extended_isinstance, False)
|
||||
self.sheerka.bind_service_method(self.is_container, False)
|
||||
self.sheerka.bind_service_method(self.format_rules, False)
|
||||
@@ -149,44 +146,6 @@ class SheerkaAdmin(BaseService):
|
||||
def format_rules(self):
|
||||
return self.sheerka.new(BuiltinConcepts.TO_LIST, items=self.sheerka.get_format_rules())
|
||||
|
||||
def last_created_concept(self, use_history=False):
|
||||
for exec_result in reversed(self.sheerka.last_executions):
|
||||
return_values = exec_result.values["return_values"]
|
||||
for ret in return_values:
|
||||
if ret.status and self.sheerka.isinstance(ret.value, BuiltinConcepts.NEW_CONCEPT):
|
||||
return ret.value.body
|
||||
|
||||
if use_history:
|
||||
return self.sheerka.new(BuiltinConcepts.ERROR, body="Not yet implement")
|
||||
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND)
|
||||
|
||||
def last_ret(self, context, index=-1):
|
||||
try:
|
||||
last = self.sheerka.last_return_values[index]
|
||||
return last[0] if isinstance(last, list) and len(last) == 1 else last
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def last_error_ret(self, context, index=-1):
|
||||
while index >= -len(self.sheerka.last_return_values):
|
||||
last = self.sheerka.last_return_values[index]
|
||||
last = [last] if not hasattr(last, "__iter__") else last
|
||||
last = [ret_val for ret_val in last if not ret_val.status]
|
||||
if len(last) == 0:
|
||||
index -= 1
|
||||
continue
|
||||
|
||||
if len(last) > 1:
|
||||
return context.sheerka.ret(SheerkaAdmin.NAME,
|
||||
False,
|
||||
context.sheerka.new(BuiltinConcepts.TOO_MANY_ERRORS, body=last))
|
||||
|
||||
return last[0]
|
||||
|
||||
return context.sheerka.ret(SheerkaAdmin.NAME,
|
||||
False,
|
||||
context.sheerka.new(BuiltinConcepts.NOT_FOUND))
|
||||
|
||||
def extended_isinstance(self, a, b):
|
||||
"""
|
||||
|
||||
@@ -3,7 +3,7 @@ from dataclasses import dataclass
|
||||
from cache.Cache import Cache
|
||||
from cache.ListCache import ListCache
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.global_symbols import CONCEPT_PRECEDENCE_MODIFIED, RULE_PRECEDENCE_MODIFIED, RULE_COMPARISON_CONTEXT, \
|
||||
from core.global_symbols import EVENT_CONCEPT_PRECEDENCE_MODIFIED, EVENT_RULE_PRECEDENCE_MODIFIED, RULE_COMPARISON_CONTEXT, \
|
||||
CONCEPT_COMPARISON_CONTEXT
|
||||
from core.builtin_helpers import ensure_concept_or_rule
|
||||
from core.concept import Concept
|
||||
@@ -183,9 +183,9 @@ class SheerkaComparisonManager(BaseService):
|
||||
|
||||
if comparison_obj.property == BuiltinConcepts.PRECEDENCE:
|
||||
if comparison_obj.context == CONCEPT_COMPARISON_CONTEXT:
|
||||
self.sheerka.publish(context, CONCEPT_PRECEDENCE_MODIFIED)
|
||||
self.sheerka.publish(context, EVENT_CONCEPT_PRECEDENCE_MODIFIED)
|
||||
elif comparison_obj.context == RULE_COMPARISON_CONTEXT:
|
||||
self.sheerka.publish(context, RULE_PRECEDENCE_MODIFIED)
|
||||
self.sheerka.publish(context, EVENT_RULE_PRECEDENCE_MODIFIED)
|
||||
|
||||
return self.sheerka.ret(self.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import core.utils
|
||||
from core.builtin_concepts import BuiltinConcepts, ErrorConcept
|
||||
from core.builtin_helpers import ensure_concept
|
||||
from core.concept import Concept, DEFINITION_TYPE_DEF, DEFINITION_TYPE_BNF, freeze_concept_attrs
|
||||
from core.global_symbols import EVENT_CONCEPT_CREATED
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
|
||||
|
||||
@@ -85,6 +86,9 @@ class SheerkaCreateNewConcept(BaseService):
|
||||
if concept.get_bnf() and init_bnf_ret_value is not None and init_bnf_ret_value.status:
|
||||
sheerka.cache_manager.clear(sheerka.CONCEPTS_GRAMMARS_ENTRY)
|
||||
|
||||
# publish the new concept
|
||||
sheerka.publish(context, EVENT_CONCEPT_CREATED, concept)
|
||||
|
||||
# process the return if needed
|
||||
ret = sheerka.ret(self.NAME, True, sheerka.new(BuiltinConcepts.NEW_CONCEPT, body=concept))
|
||||
return ret
|
||||
|
||||
@@ -1,20 +1,57 @@
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, NotInit
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from core.utils import CONSOLE_COLORS_MAP as CCM
|
||||
from core.utils import CONSOLE_COLORS_MAP as CCM, CONSOLE_COLUMNS, PRIMITIVES_TYPES
|
||||
from core.utils import evaluate_expression, as_bag
|
||||
|
||||
try:
|
||||
rows, columns = os.popen('stty size', 'r').read().split()
|
||||
except ValueError:
|
||||
rows, columns = 50, 80
|
||||
pp = pprint.PrettyPrinter(indent=2, width=CONSOLE_COLUMNS)
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=2, width=columns)
|
||||
NotFound = "** Not Found **"
|
||||
|
||||
|
||||
class ConceptDebugObj:
|
||||
def __init__(self, concept):
|
||||
self.concept = concept
|
||||
self.attrs = concept.as_debug_bag(lambda x: ConceptDebugObj(x), True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"({self.concept_repr()})"
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, ConceptDebugObj):
|
||||
return False
|
||||
|
||||
return self.attrs == other.attrs
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.concept)
|
||||
|
||||
def concept_repr(self):
|
||||
res = f":{self.concept.name}|{self.concept.id}:"
|
||||
|
||||
# print metadata
|
||||
first = True
|
||||
for k, v in [(k, v) for k, v in self.attrs.items() if k not in ("id", "name", "key")]:
|
||||
if not first:
|
||||
res += ", "
|
||||
res += f"{k}={v}"
|
||||
first = False
|
||||
|
||||
return res
|
||||
|
||||
|
||||
class ConceptNodeDebugObj:
|
||||
def __init__(self, concept_node):
|
||||
self.concept_node = concept_node
|
||||
self.concept_debug = ConceptDebugObj(concept_node.concept)
|
||||
|
||||
def __repr__(self):
|
||||
return f"ConceptNode({self.concept_debug.concept_repr()})"
|
||||
|
||||
|
||||
class BaseDebugLogger:
|
||||
@@ -49,6 +86,9 @@ class BaseDebugLogger:
|
||||
def is_enabled(self):
|
||||
pass
|
||||
|
||||
def get_enabled_vars(self):
|
||||
pass
|
||||
|
||||
|
||||
class NullDebugLogger(BaseDebugLogger):
|
||||
def __init__(self):
|
||||
@@ -57,6 +97,9 @@ class NullDebugLogger(BaseDebugLogger):
|
||||
def is_enabled(self):
|
||||
return False
|
||||
|
||||
def get_enabled_vars(self):
|
||||
pass
|
||||
|
||||
|
||||
class ConsoleDebugLogger(BaseDebugLogger):
|
||||
|
||||
@@ -70,9 +113,29 @@ class ConsoleDebugLogger(BaseDebugLogger):
|
||||
self.is_highlighted = ""
|
||||
|
||||
def is_enabled(self):
|
||||
"""
|
||||
True if the debug is activated for the current service, method and context
|
||||
:return:
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_enabled_vars(self):
|
||||
"""
|
||||
Returns the list of all enabled variables for this console debugger
|
||||
:return:
|
||||
"""
|
||||
return self.debug_manager.get_enabled_items("vars",
|
||||
self.context,
|
||||
self.service_name,
|
||||
self.method_name,
|
||||
self.debug_id)
|
||||
|
||||
def debug_entering(self, **kwargs):
|
||||
"""
|
||||
Log that we start debugging a method (for a specified service and context)
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
super().debug_entering(**kwargs)
|
||||
|
||||
str_text = f"{CCM['blue']}Entering {self.service_name}.{self.method_name} with {CCM['reset']}"
|
||||
@@ -84,10 +147,24 @@ class ConsoleDebugLogger(BaseDebugLogger):
|
||||
self.debug_manager.debug(self.prefix() + str_vars)
|
||||
|
||||
def debug_log(self, text, is_error=False):
|
||||
"""
|
||||
Prints a debug information (not related to a specific variable, concept or rule)
|
||||
:param text:
|
||||
:param is_error:
|
||||
:return:
|
||||
"""
|
||||
color = 'red' if is_error else 'blue'
|
||||
self.debug_manager.debug(self.prefix() + f"{CCM[color]}..{text}{CCM['reset']}")
|
||||
|
||||
def debug_var(self, name, value, is_error=False, hint=None):
|
||||
"""
|
||||
Prints the value of a variable
|
||||
:param name:
|
||||
:param value:
|
||||
:param is_error:
|
||||
:param hint:
|
||||
:return:
|
||||
"""
|
||||
enabled = is_error or self.debug_manager.compute_debug_var(self.context,
|
||||
self.service_name,
|
||||
self.method_name,
|
||||
@@ -103,6 +180,12 @@ class ConsoleDebugLogger(BaseDebugLogger):
|
||||
self.debug(str_text, str_vars)
|
||||
|
||||
def debug_rule(self, rule, results):
|
||||
"""
|
||||
Prints debug information related to a specific rule id
|
||||
:param rule:
|
||||
:param results:
|
||||
:return:
|
||||
"""
|
||||
if not self.debug_manager.compute_debug_rule(self.context,
|
||||
self.service_name,
|
||||
self.method_name,
|
||||
@@ -115,6 +198,13 @@ class ConsoleDebugLogger(BaseDebugLogger):
|
||||
self.debug(str_text, str_vars)
|
||||
|
||||
def debug_concept(self, concept, text=None, **kwargs):
|
||||
"""
|
||||
Prints debug information related to a specific concept
|
||||
:param concept:
|
||||
:param text:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
raw = kwargs.pop('raw', None)
|
||||
if not self.debug_manager.compute_debug_concept(self.context,
|
||||
self.service_name,
|
||||
@@ -283,27 +373,6 @@ class SheerkaDebugManager(BaseService):
|
||||
|
||||
return debug_for_self, debug_for_children
|
||||
|
||||
def inspect(self, context, context_id, *props):
|
||||
"""
|
||||
Print
|
||||
:param context:
|
||||
:param context_id:
|
||||
:return:
|
||||
"""
|
||||
to_inspect = self.sheerka.get_execution_item(context, context_id)
|
||||
if not isinstance(to_inspect, ExecutionContext):
|
||||
return to_inspect
|
||||
|
||||
if not props:
|
||||
props = ["inputs", "values.return_values"]
|
||||
|
||||
bag = as_bag(to_inspect)
|
||||
res = {}
|
||||
for prop in props:
|
||||
res[prop] = evaluate_expression(prop, bag)
|
||||
|
||||
return self.sheerka.new(BuiltinConcepts.TO_DICT, body=res)
|
||||
|
||||
def debug(self, *args, **kwargs):
|
||||
print(*args, **kwargs)
|
||||
|
||||
@@ -428,6 +497,24 @@ class SheerkaDebugManager(BaseService):
|
||||
|
||||
return res
|
||||
|
||||
def get_enabled_items(self, item_type, context, service_name, method_name, debug_id):
|
||||
if not self.activated:
|
||||
return False
|
||||
|
||||
selected = set()
|
||||
for setting in getattr(self, self.container_name(item_type)):
|
||||
if not setting.enabled or setting.item is None:
|
||||
continue
|
||||
|
||||
if (setting.service_name is None or setting.service_name == service_name) and \
|
||||
(setting.method_name is None or setting.method_name == method_name) and \
|
||||
(setting.context_id is None or setting.context_id == context.id or (
|
||||
setting.context_children and context.has_parent(setting.context_id))) and \
|
||||
(setting.debug_id is None or setting.debug_id == debug_id):
|
||||
selected.add(setting.item)
|
||||
|
||||
return selected
|
||||
|
||||
def reset_debug(self, context):
|
||||
for item_type in ["vars", "rules", "concepts"]:
|
||||
setting_name = self.container_name(item_type)
|
||||
@@ -487,6 +574,123 @@ class SheerkaDebugManager(BaseService):
|
||||
def compute_debug_rule(self, context, service_name, method_name, item, debug_id):
|
||||
return self.compute_debug_item("rules", context, service_name, method_name, item, debug_id)
|
||||
|
||||
def inspect(self, context, *args, **kwargs):
|
||||
"""
|
||||
Print
|
||||
:param context:
|
||||
:param args: 1st parameter is what to display, the other are the properties to display
|
||||
:param kwargs: how to display the result
|
||||
:return:
|
||||
"""
|
||||
|
||||
if len(args) == 0:
|
||||
return
|
||||
|
||||
forced_prop, props = None, None
|
||||
if isinstance(args[0], int):
|
||||
to_inspect = self.sheerka.get_execution_item(context, int(args[0]))
|
||||
if isinstance(to_inspect, ExecutionContext):
|
||||
if len(args) == 1:
|
||||
props = ["inputs", "values.return_values"]
|
||||
else:
|
||||
props = args[1:]
|
||||
else:
|
||||
props = None
|
||||
else:
|
||||
to_inspect = args[0]
|
||||
if isinstance(to_inspect, Concept):
|
||||
if len(args) > 1:
|
||||
forced_prop = args[1:]
|
||||
props = forced_prop
|
||||
else:
|
||||
props = args[1:]
|
||||
|
||||
bag = self.as_debug_bag(to_inspect, False, forced_prop)
|
||||
props = props or list(bag.keys())
|
||||
|
||||
res = self.inspect_object(bag, props, False, **kwargs)
|
||||
|
||||
# Attributes that are not found are probably directly requested by the user
|
||||
# Let's try for the full names of these attributes
|
||||
not_found = {k: v for k, v in [(k, v) for k, v in res.items() if v == NotFound]}
|
||||
if len(not_found) > 0:
|
||||
to_add = {}
|
||||
to_remove = []
|
||||
|
||||
for k, v in not_found.items():
|
||||
alternate_props = ["meta." + k, "compiled." + k, "value." + k]
|
||||
res2 = self.inspect_object(bag, alternate_props, True, **kwargs)
|
||||
if len(res2) > 0:
|
||||
to_add.update(res2)
|
||||
to_remove.append(k)
|
||||
|
||||
res.update(to_add)
|
||||
for k in to_remove:
|
||||
del res[k]
|
||||
|
||||
return self.sheerka.new(BuiltinConcepts.TO_DICT, body=res)
|
||||
|
||||
def inspect_object(self, bag, props, discard_not_found, **kwargs):
|
||||
values_required = kwargs.get("values", False)
|
||||
as_bag_required = kwargs.get("as_bag", False)
|
||||
|
||||
res = {}
|
||||
for prop in props:
|
||||
if prop in res:
|
||||
# discard duplicates
|
||||
continue
|
||||
|
||||
try:
|
||||
value = bag[prop] if prop.startswith("#") else evaluate_expression(prop, bag)
|
||||
except NameError:
|
||||
if discard_not_found:
|
||||
continue
|
||||
else:
|
||||
value = NotFound
|
||||
|
||||
if callable(value):
|
||||
# discard methods
|
||||
continue
|
||||
|
||||
if values_required:
|
||||
value = self.get_inner_values(value, **kwargs)
|
||||
elif as_bag_required:
|
||||
value = self.get_debug_repr(value, **kwargs)
|
||||
|
||||
res[prop] = value
|
||||
return res
|
||||
|
||||
def get_inner_values(self, obj, **kwargs):
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if isinstance(obj, list):
|
||||
return [self.get_inner_values(item, **kwargs) for item in obj]
|
||||
|
||||
if hasattr(obj, "get_obj_value"):
|
||||
return obj.get_obj_value()
|
||||
|
||||
if not isinstance(obj, Concept):
|
||||
return self.get_debug_repr(obj, **kwargs)
|
||||
|
||||
if obj.body is NotInit:
|
||||
return self.get_debug_repr(obj, **kwargs)
|
||||
|
||||
return self.get_inner_values(obj.body, **kwargs)
|
||||
|
||||
def get_debug_repr(self, obj, **kwargs):
|
||||
if kwargs.get("as_bag", False):
|
||||
forced_props = self.get_concept_forced_props(obj) if isinstance(obj, Concept) else None
|
||||
return self.as_debug_bag(obj, True, forced_props)
|
||||
|
||||
from parsers.BaseNodeParser import ConceptNode
|
||||
if isinstance(obj, Concept):
|
||||
return ConceptDebugObj(obj)
|
||||
elif isinstance(obj, ConceptNode):
|
||||
return ConceptNodeDebugObj(obj)
|
||||
else:
|
||||
return obj
|
||||
|
||||
@staticmethod
|
||||
def container_name(item_type):
|
||||
return f"debug_{item_type}_settings"
|
||||
@@ -505,7 +709,7 @@ class SheerkaDebugManager(BaseService):
|
||||
if len(parts) > 1:
|
||||
method_name = None if parts[1] == "*" else parts[1]
|
||||
if len(parts) > 2:
|
||||
item = parts[2]
|
||||
item = ".".join(parts[2:])
|
||||
|
||||
if len(args) > 1:
|
||||
context_part = args[1]
|
||||
@@ -535,139 +739,22 @@ class SheerkaDebugManager(BaseService):
|
||||
|
||||
return item, service, method_name, context_id, context_children, debug_id, enabled
|
||||
|
||||
# def debug_rule(self, context, rule=None, context_id=None, debug_id=None, enabled=True):
|
||||
# """
|
||||
# Add a debug rule request
|
||||
# :param context:
|
||||
# :param rule:
|
||||
# :param context_id:
|
||||
# :param debug_id:
|
||||
# :param enabled:
|
||||
# :return:
|
||||
# """
|
||||
# rule = str(rule) if rule is not None else None
|
||||
# for setting in self.debug_rules_settings:
|
||||
# if setting.rule_id == rule and \
|
||||
# setting.context_id == context_id and \
|
||||
# setting.debug_id == debug_id:
|
||||
# setting.enabled = enabled
|
||||
# break
|
||||
# else:
|
||||
# self.debug_rules_settings.append(DebugRuleSetting(rule,
|
||||
# context_id,
|
||||
# debug_id,
|
||||
# enabled))
|
||||
#
|
||||
# self.sheerka.record_var(context, self.NAME, "debug_rules_settings", self.debug_rules_settings)
|
||||
# return self.sheerka.ret(SheerkaDebugManager.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||
#
|
||||
# def debug_concept(self, context, concept=None, context_id=None, debug_id=None, enabled=True):
|
||||
# """
|
||||
# Add a debug rule request
|
||||
# :param context:
|
||||
# :param concept:
|
||||
# :param context_id:
|
||||
# :param debug_id:
|
||||
# :param enabled:
|
||||
# :return:
|
||||
# """
|
||||
# concept_id = concept.id if isinstance(concept, Concept) else str(concept) if concept is not None else None
|
||||
# for setting in self.debug_concepts_settings:
|
||||
# if setting.concept_id == concept_id and \
|
||||
# setting.context_id == context_id and \
|
||||
# setting.debug_id == debug_id:
|
||||
# setting.enabled = enabled
|
||||
# break
|
||||
# else:
|
||||
# self.debug_concepts_settings.append(DebugConceptSetting(concept_id,
|
||||
# context_id,
|
||||
# debug_id,
|
||||
# enabled))
|
||||
#
|
||||
# self.sheerka.record_var(context, self.NAME, "debug_concepts_settings", self.debug_concepts_settings)
|
||||
# return self.sheerka.ret(SheerkaDebugManager.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||
#
|
||||
@staticmethod
|
||||
def get_concept_forced_props(concept):
|
||||
return ["id", "name", "key"] + [p for p in concept.__dict__ if not p.startswith("_")]
|
||||
|
||||
#
|
||||
@staticmethod
|
||||
def as_debug_bag(obj, recurse=True, forced_props=None):
|
||||
if type(obj) in PRIMITIVES_TYPES:
|
||||
return obj
|
||||
|
||||
# def compute_debug_var(self, service_name, method_name, context_id, variable_name, debug_id):
|
||||
# if not self.activated:
|
||||
# return False
|
||||
#
|
||||
# selected = []
|
||||
# for setting in self.debug_vars_settings:
|
||||
# if setting.variable_name is None and setting.debug_id is None:
|
||||
# continue
|
||||
#
|
||||
# if (setting.service_name is None or setting.service_name == service_name) and \
|
||||
# (setting.method_name is None or setting.method_name == method_name) and \
|
||||
# (setting.context_id is None or setting.context_id == context_id) and \
|
||||
# (setting.variable_name is None or
|
||||
# setting.variable_name == "*" or
|
||||
# setting.variable_name == variable_name) and \
|
||||
# (setting.debug_id is None or setting.debug_id == debug_id):
|
||||
# selected.append(setting.enabled)
|
||||
#
|
||||
# if len(selected) == 0:
|
||||
# return False
|
||||
#
|
||||
# res = selected[0]
|
||||
# for enabled in selected[1:]:
|
||||
# if res == False or enabled == False:
|
||||
# return False
|
||||
#
|
||||
# if isinstance(res, str):
|
||||
# continue
|
||||
#
|
||||
# res = enabled
|
||||
#
|
||||
# return res
|
||||
#
|
||||
# def compute_debug_rule(self, rule_id, context_id, debug_id):
|
||||
# if not self.activated:
|
||||
# return False
|
||||
#
|
||||
# selected = []
|
||||
# for setting in self.debug_rules_settings:
|
||||
# if (setting.rule_id is None or setting.rule_id == rule_id) and \
|
||||
# (setting.context_id is None or setting.context_id == context_id) and \
|
||||
# (setting.debug_id is None or setting.debug_id == debug_id):
|
||||
# selected.append(setting.enabled)
|
||||
#
|
||||
# if len(selected) == 0:
|
||||
# return False
|
||||
#
|
||||
# res = selected[0]
|
||||
# for enabled in selected[1:]:
|
||||
# res &= enabled
|
||||
#
|
||||
# return res
|
||||
#
|
||||
# def compute_debug_concept(self, concept_id, context_id, debug_id):
|
||||
# if not self.activated:
|
||||
# return False
|
||||
#
|
||||
# selected = []
|
||||
# for setting in self.debug_concepts_settings:
|
||||
# if (setting.concept_id is None or setting.concept_id == concept_id) and \
|
||||
# (setting.context_id is None or setting.context_id == context_id) and \
|
||||
# (setting.debug_id is None or setting.debug_id == debug_id):
|
||||
# selected.append(setting.enabled)
|
||||
#
|
||||
# if len(selected) == 0:
|
||||
# return False
|
||||
#
|
||||
# res = selected[0]
|
||||
# for enabled in selected[1:]:
|
||||
# res &= enabled
|
||||
#
|
||||
# return res
|
||||
#
|
||||
# def reset_debug_rules(self, context):
|
||||
# self.debug_rules_settings.clear()
|
||||
# self.sheerka.record_var(context, self.NAME, "debug_rules_settings", self.debug_rules_settings)
|
||||
# return self.sheerka.ret(SheerkaDebugManager.NAME, True, self.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||
#
|
||||
# def get_debug_settings(self):
|
||||
# lst = self.debug_vars_settings + self.debug_concepts_settings + self.debug_rules_settings
|
||||
# return self.sheerka.new(BuiltinConcepts.TO_LIST, body=lst)
|
||||
res = {'#type#': type(obj).__name__}
|
||||
if isinstance(obj, Concept) and not obj.get_metadata().is_builtin:
|
||||
res.update(obj.as_debug_bag(SheerkaDebugManager.as_debug_bag, recurse))
|
||||
|
||||
else:
|
||||
forced_props_to_use = [p for p in forced_props if p != "#type#"] if forced_props else None
|
||||
res.update(as_bag(obj, forced_props_to_use))
|
||||
del res["self"]
|
||||
|
||||
return res
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import os
|
||||
import pprint
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from core.utils import CONSOLE_COLUMNS
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||
|
||||
|
||||
def get_pp():
|
||||
rows, columns = os.popen('stty size', 'r').read().split()
|
||||
pp = pprint.PrettyPrinter(width=columns, compact=True)
|
||||
pp = pprint.PrettyPrinter(width=CONSOLE_COLUMNS, compact=True)
|
||||
return pp
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from cache.FastCache import FastCache
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import CONTEXT_DISPOSED
|
||||
from core.global_symbols import EVENT_CONTEXT_DISPOSED
|
||||
from core.sheerka.services.sheerka_service import BaseService, ServiceObj
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class SheerkaMemory(BaseService):
|
||||
def __init__(self, sheerka):
|
||||
super().__init__(sheerka)
|
||||
self.short_term_objects = FastCache()
|
||||
self.objects = ListIfNeededCache(default=lambda k: self.sheerka.sdp.get(self.OBJECTS_ENTRY, k))
|
||||
self.memory_objects = ListIfNeededCache(default=lambda k: self.sheerka.sdp.get(self.OBJECTS_ENTRY, k))
|
||||
self.registration = {}
|
||||
|
||||
def initialize(self):
|
||||
@@ -37,14 +37,16 @@ class SheerkaMemory(BaseService):
|
||||
self.sheerka.bind_service_method(self.unregister_object, True, visible=False)
|
||||
self.sheerka.bind_service_method(self.add_registered_objects, True, visible=False)
|
||||
self.sheerka.bind_service_method(self.memory, False)
|
||||
self.sheerka.bind_service_method(self.mem, False)
|
||||
|
||||
self.sheerka.cache_manager.register_cache(self.OBJECTS_ENTRY, self.objects, persist=True, use_ref=True)
|
||||
self.sheerka.cache_manager.register_cache(self.OBJECTS_ENTRY, self.memory_objects, persist=True, use_ref=True)
|
||||
|
||||
def reset(self):
|
||||
self.short_term_objects.clear()
|
||||
self.memory_objects.clear()
|
||||
|
||||
def initialize_deferred(self, context, is_first_time):
|
||||
self.sheerka.subscribe(CONTEXT_DISPOSED, self.remove_context)
|
||||
self.sheerka.subscribe(EVENT_CONTEXT_DISPOSED, self.remove_context)
|
||||
|
||||
def get_from_short_term_memory(self, context, key):
|
||||
while True:
|
||||
@@ -90,16 +92,16 @@ class SheerkaMemory(BaseService):
|
||||
:param concept:
|
||||
:return:
|
||||
"""
|
||||
self.objects.put(key, MemoryObject(context.event.get_digest(), concept))
|
||||
self.memory_objects.put(key, MemoryObject(context.event.get_digest(), concept))
|
||||
|
||||
def get_from_memory(self, context, key):
|
||||
""""
|
||||
"""
|
||||
return self.objects.get(key)
|
||||
return self.memory_objects.get(key)
|
||||
|
||||
def register_object(self, context, key, concept):
|
||||
"""
|
||||
Before adding objects to memory, they first need to be registered
|
||||
Before adding memory_objects to memory, they first need to be registered
|
||||
More:
|
||||
We don't want to add all evaluated concept into memory
|
||||
(because some of them may be ref to concept already in memory)
|
||||
@@ -126,7 +128,7 @@ class SheerkaMemory(BaseService):
|
||||
|
||||
def add_registered_objects(self, context):
|
||||
"""
|
||||
Adds all registered objects
|
||||
Adds all registered memory_objects
|
||||
:param context:
|
||||
:return:
|
||||
"""
|
||||
@@ -136,7 +138,7 @@ class SheerkaMemory(BaseService):
|
||||
|
||||
def memory(self, context, name=None):
|
||||
"""
|
||||
Get the list of all objects in memory
|
||||
Get the list of all memory_objects in memory
|
||||
:param context:
|
||||
:param name:
|
||||
:return:
|
||||
@@ -154,10 +156,14 @@ class SheerkaMemory(BaseService):
|
||||
return obj.obj
|
||||
|
||||
res = {}
|
||||
for k in self.objects:
|
||||
obj = self.objects.get(k)
|
||||
for k in self.memory_objects:
|
||||
obj = self.memory_objects.get(k)
|
||||
if isinstance(obj, list):
|
||||
obj = obj[-1]
|
||||
res[k] = obj.obj
|
||||
|
||||
return res
|
||||
|
||||
def mem(self):
|
||||
keys = sorted([k for k in self.memory_objects])
|
||||
return {"keys": keys, "len": len(keys)}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import ast
|
||||
|
||||
from cache.Cache import Cache
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.global_symbols import EVENT_USER_INPUT_EVALUATED, EVENT_CONCEPT_CREATED
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from core.utils import CONSOLE_COLORS_MAP as CCM
|
||||
from core.utils import as_bag
|
||||
|
||||
MAX_EXECUTION_HISTORY = 100
|
||||
|
||||
|
||||
class SheerkaResultConcept(BaseService):
|
||||
NAME = "Result"
|
||||
@@ -11,6 +16,10 @@ class SheerkaResultConcept(BaseService):
|
||||
def __init__(self, sheerka, page_size=30):
|
||||
super().__init__(sheerka)
|
||||
self.page_size = page_size
|
||||
self.executions_contexts_cache = Cache(MAX_EXECUTION_HISTORY)
|
||||
self.last_execution = None
|
||||
self.last_created_concept = None
|
||||
self.last_created_concept_id = None
|
||||
|
||||
def initialize(self):
|
||||
self.sheerka.bind_service_method(self.get_results_by_digest, True) # digest is recorded
|
||||
@@ -18,6 +27,19 @@ class SheerkaResultConcept(BaseService):
|
||||
self.sheerka.bind_service_method(self.get_last_results, True) # digest is recorded
|
||||
self.sheerka.bind_service_method(self.get_results, False)
|
||||
self.sheerka.bind_service_method(self.get_execution_item, False)
|
||||
self.sheerka.bind_service_method(self.get_last_ret, False, as_name="last_ret")
|
||||
self.sheerka.bind_service_method(self.get_last_created_concept, False, as_name="last_created_concept")
|
||||
|
||||
def initialize_deferred(self, context, is_first_time):
|
||||
self.restore_values("last_created_concept_id")
|
||||
self.sheerka.subscribe(EVENT_USER_INPUT_EVALUATED, self.user_input_evaluated)
|
||||
self.sheerka.subscribe(EVENT_CONCEPT_CREATED, self.new_concept_created)
|
||||
|
||||
def reset(self):
|
||||
self.executions_contexts_cache.clear()
|
||||
self.last_execution = None
|
||||
self.last_created_concept = None
|
||||
self.last_created_concept_id = None
|
||||
|
||||
@staticmethod
|
||||
def get_predicate(**kwargs):
|
||||
@@ -38,12 +60,24 @@ class SheerkaResultConcept(BaseService):
|
||||
predicate = " and ".join(res)
|
||||
return compile(ast.parse(predicate, mode="eval"), "<SheerkaResultManager.get_predicate>", mode="eval")
|
||||
|
||||
@staticmethod
|
||||
def as_list(execution_context, predicate):
|
||||
def _yield_result(lst):
|
||||
for e in lst:
|
||||
if predicate is None or eval(predicate, as_bag(e)):
|
||||
yield e
|
||||
|
||||
if e._children:
|
||||
yield from _yield_result(e._children)
|
||||
|
||||
return _yield_result([execution_context])
|
||||
|
||||
def get_results_by_digest(self, context, digest, filter=None, record_digest=True, **kwargs):
|
||||
"""
|
||||
Gets the entire execution tree for the given event digest
|
||||
:param filter:
|
||||
:param context:
|
||||
:param digest:
|
||||
:param filter:
|
||||
:param record_digest:
|
||||
:return:
|
||||
"""
|
||||
@@ -54,8 +88,12 @@ class SheerkaResultConcept(BaseService):
|
||||
kwargs["filter"] = filter
|
||||
|
||||
try:
|
||||
result = self.sheerka.sdp.load_result(digest)
|
||||
event = self.sheerka.sdp.load_event(digest)
|
||||
if digest in self.executions_contexts_cache:
|
||||
result = self.executions_contexts_cache.get(digest)
|
||||
event = result.event
|
||||
else:
|
||||
result = self.sheerka.sdp.load_result(digest)
|
||||
event = self.sheerka.sdp.load_event(digest) # there is no real need for a cache of the events
|
||||
|
||||
if record_digest:
|
||||
context.log(f"Recording digest '{digest}'")
|
||||
@@ -89,7 +127,18 @@ class SheerkaResultConcept(BaseService):
|
||||
if command is None:
|
||||
return None
|
||||
|
||||
start = 0
|
||||
# first, search in cache
|
||||
for event_id in self.executions_contexts_cache:
|
||||
execution_context = self.executions_contexts_cache.get(event_id)
|
||||
if execution_context.event.message.startswith(command):
|
||||
return self.get_results_by_digest(context,
|
||||
execution_context.event.get_digest(),
|
||||
filter,
|
||||
record_digest,
|
||||
**kwargs)
|
||||
|
||||
# not found, search in db
|
||||
start = len(self.executions_contexts_cache)
|
||||
consumed = 0
|
||||
while True:
|
||||
for event in self.sheerka.sdp.load_events(self.page_size, start):
|
||||
@@ -103,6 +152,7 @@ class SheerkaResultConcept(BaseService):
|
||||
start += self.page_size
|
||||
consumed = 0
|
||||
|
||||
# not found, return error
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"command": command})
|
||||
|
||||
def get_last_results(self, context, filter=None, record_digest=True, **kwargs):
|
||||
@@ -114,23 +164,16 @@ class SheerkaResultConcept(BaseService):
|
||||
:return:
|
||||
"""
|
||||
|
||||
start = 0
|
||||
page_size = 2
|
||||
consumed = 0
|
||||
while True:
|
||||
for event in self.sheerka.sdp.load_events(page_size, start):
|
||||
consumed += 1
|
||||
if self.sheerka.sdp.has_result(event.get_digest()):
|
||||
return self.get_results_by_digest(context, event.get_digest(), filter, record_digest, **kwargs)
|
||||
if self.last_execution:
|
||||
return self.get_results_by_digest(context,
|
||||
self.last_execution.event.get_digest(),
|
||||
filter,
|
||||
record_digest,
|
||||
**kwargs)
|
||||
|
||||
if consumed < page_size:
|
||||
break
|
||||
|
||||
if page_size < 100:
|
||||
page_size *= 2
|
||||
|
||||
start += page_size
|
||||
consumed = 0
|
||||
event_id = self._get_last_execution_result_event_id_from_db()
|
||||
if event_id is not None:
|
||||
return self.get_results_by_digest(context, event_id, filter, record_digest, **kwargs)
|
||||
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"query": "last"})
|
||||
|
||||
@@ -150,12 +193,21 @@ class SheerkaResultConcept(BaseService):
|
||||
return self.get_results_by_digest(context, digest, filter, False, **kwargs)
|
||||
|
||||
def get_execution_item(self, context, item_id):
|
||||
"""
|
||||
Return the item_id'th element of the execution result under investigation
|
||||
:param context:
|
||||
:param item_id:
|
||||
:return:
|
||||
"""
|
||||
digest = self.sheerka.load_var(self.NAME, "digest")
|
||||
if digest is None:
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body="no digest")
|
||||
|
||||
try:
|
||||
result = self.sheerka.sdp.load_result(digest)
|
||||
if digest in self.executions_contexts_cache:
|
||||
result = self.executions_contexts_cache.get(digest)
|
||||
else:
|
||||
result = self.sheerka.sdp.load_result(digest)
|
||||
items = list(self.as_list(result, self.get_predicate(id=item_id)))
|
||||
|
||||
if len(items) == 0:
|
||||
@@ -167,14 +219,77 @@ class SheerkaResultConcept(BaseService):
|
||||
context.log_error(f"Digest {digest} is not found.", self.NAME, ex)
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"digest": digest})
|
||||
|
||||
@staticmethod
|
||||
def as_list(execution_context, predicate):
|
||||
def _yield_result(lst):
|
||||
for e in lst:
|
||||
if predicate is None or eval(predicate, as_bag(e)):
|
||||
yield e
|
||||
def user_input_evaluated(self, execution_context):
|
||||
"""
|
||||
Callback that updates the cache of execution contexts
|
||||
:param execution_context:
|
||||
:return:
|
||||
"""
|
||||
if self.sheerka.save_execution_context:
|
||||
try:
|
||||
self.sheerka.sdp.save_result(execution_context)
|
||||
except Exception as ex:
|
||||
print(f"{CCM['red']}Failed to save execution context. Reason: {ex}{CCM['reset']}")
|
||||
pass
|
||||
# self.log.error(f"Failed to save execution context. Reason: {ex}")
|
||||
|
||||
if e._children:
|
||||
yield from _yield_result(e._children)
|
||||
self.executions_contexts_cache.put(execution_context.event.get_digest(), execution_context)
|
||||
self.last_execution = execution_context
|
||||
|
||||
return _yield_result([execution_context])
|
||||
def get_last_ret(self, context):
|
||||
"""
|
||||
Return the last return value(s)
|
||||
:return:
|
||||
"""
|
||||
if self.last_execution:
|
||||
return self.last_execution.values["return_values"]
|
||||
|
||||
event_id = self._get_last_execution_result_event_id_from_db()
|
||||
if event_id is not None:
|
||||
try:
|
||||
|
||||
execution_result = self.sheerka.sdp.load_result(event_id)
|
||||
return execution_result.values["return_values"]
|
||||
|
||||
except FileNotFoundError as ex:
|
||||
context.log_error(f"Digest {event_id} is not found.", self.NAME, ex)
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"digest": event_id})
|
||||
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"query": "last"})
|
||||
|
||||
def new_concept_created(self, context, concept):
|
||||
self.last_created_concept = concept
|
||||
self.last_created_concept_id = concept.id
|
||||
|
||||
self.sheerka.record_var(context, self.NAME, "last_created_concept_id", concept.id)
|
||||
|
||||
def get_last_created_concept(self, context):
|
||||
if self.last_created_concept:
|
||||
return self.last_created_concept
|
||||
|
||||
if self.last_created_concept_id:
|
||||
self.last_created_concept = self.sheerka.new((None, self.last_created_concept_id))
|
||||
return self.last_created_concept
|
||||
|
||||
return self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"query": "last_created_concept"})
|
||||
|
||||
def _get_last_execution_result_event_id_from_db(self):
|
||||
start = 0
|
||||
page_size = 2
|
||||
consumed = 0
|
||||
while True:
|
||||
for event in self.sheerka.sdp.load_events(page_size, start):
|
||||
consumed += 1
|
||||
if self.sheerka.sdp.has_result(event.get_digest()):
|
||||
return event.get_digest()
|
||||
|
||||
if consumed < page_size:
|
||||
break
|
||||
|
||||
if page_size < 100:
|
||||
page_size *= 2
|
||||
|
||||
start += page_size
|
||||
consumed = 0
|
||||
|
||||
return None
|
||||
|
||||
@@ -7,7 +7,7 @@ from cache.Cache import Cache
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
|
||||
from core.builtin_helpers import parse_unrecognized, only_successful, ensure_rule
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import RULE_PRECEDENCE_MODIFIED, RULE_COMPARISON_CONTEXT
|
||||
from core.global_symbols import EVENT_RULE_PRECEDENCE_MODIFIED, RULE_COMPARISON_CONTEXT
|
||||
from core.rule import Rule
|
||||
from core.sheerka.services.sheerka_service import BaseService
|
||||
from core.tokenizer import Keywords, TokenKind, Token, IterParser
|
||||
@@ -112,13 +112,14 @@ class FormatAstList(FormatAstNode):
|
||||
prefix: str = None
|
||||
suffix: str = None
|
||||
show_index: bool = False
|
||||
index: object = None
|
||||
|
||||
items: object = None
|
||||
|
||||
def clone(self, **kwargs):
|
||||
return super().clone(
|
||||
FormatAstList(self.variable),
|
||||
("items_prop", "recurse_on", "recursion_depth", "debug", "prefix", "suffix", "show_index", "items"),
|
||||
("items_prop", "recurse_on", "recursion_depth", "debug", "prefix", "suffix", "show_index", "index", "items"),
|
||||
**kwargs)
|
||||
|
||||
|
||||
@@ -496,10 +497,12 @@ class SheerkaRuleManager(BaseService):
|
||||
if is_first_time:
|
||||
# add builtin rules if it's the first initialization of Sheerka
|
||||
self.init_builtin_rules(context)
|
||||
|
||||
# adds the other rules (when it's not the first time)
|
||||
self.format_rule_cache.populate(lambda: self.sheerka.sdp.list(self.FORMAT_RULE_ENTRY), lambda rule: rule.id)
|
||||
self.exec_rule_cache.populate(lambda: self.sheerka.sdp.list(self.EXEC_RULE_ENTRY), lambda rule: rule.id)
|
||||
else:
|
||||
# adds the other rules (when it's not the first time)
|
||||
self.format_rule_cache.populate(lambda: self.sheerka.sdp.list(self.FORMAT_RULE_ENTRY), lambda rule: rule.id)
|
||||
self.exec_rule_cache.populate(lambda: self.sheerka.sdp.list(self.EXEC_RULE_ENTRY), lambda rule: rule.id)
|
||||
self.format_rule_cache.reset_events()
|
||||
self.exec_rule_cache.reset_events()
|
||||
|
||||
# compile all the rules
|
||||
for rule_id in self.format_rule_cache:
|
||||
@@ -508,7 +511,7 @@ class SheerkaRuleManager(BaseService):
|
||||
# update rules priorities
|
||||
self.update_rules_priorities(context)
|
||||
|
||||
self.sheerka.subscribe(RULE_PRECEDENCE_MODIFIED, self.update_rules_priorities)
|
||||
self.sheerka.subscribe(EVENT_RULE_PRECEDENCE_MODIFIED, self.update_rules_priorities)
|
||||
|
||||
def update_rules_priorities(self, context):
|
||||
"""
|
||||
|
||||
@@ -43,6 +43,7 @@ class SheerkaSetsManager(BaseService):
|
||||
context.log(f"Setting concept {concept} is a {concept_set}", who=self.NAME)
|
||||
core.builtin_helpers.ensure_concept(concept, concept_set)
|
||||
|
||||
|
||||
if BuiltinConcepts.ISA in concept.get_metadata().props and concept_set in concept.get_metadata().props[
|
||||
BuiltinConcepts.ISA]:
|
||||
return self.sheerka.ret(
|
||||
|
||||
Reference in New Issue
Block a user