# Agenten Plattform # # (c) 2024 Magnus Bender # Institute of Humanities-Centered Artificial Intelligence (CHAI) # Universitaet Hamburg # https://www.chai.uni-hamburg.de/~bender # # source code released under the terms of GNU Public License Version 3 # https://www.gnu.org/licenses/gpl-3.0.txt import re, random from typing import Callable from ums.agent import SolveAgent from ums.utils import Riddle, RiddleData, RiddleSolution, RiddleDataType, AgentMessage class SimpleSolveAgent(SolveAgent): def before_response(self, response: AgentMessage, send_it: Callable[[], None]) -> bool: # do not send a response, if this is not a calculator riddle! return not self.stop_response def handle(self, riddle: Riddle, data: RiddleData) -> RiddleSolution: # remove whitespace expression = riddle.question.strip() # this is a very simple calculator, if the riddle it not for the calculator # just do not try to solve it and do not answer management! if "[Taschenrechner]" in riddle.context: self.stop_response = False # get all the extracted values var_vals = {} used_data = [] for d in data: e = self.get_extracted(d) if not e is None \ and "variable" in e.other and "value" in e.other \ and e.other["variable"] in expression: used_data.append(d) var_vals[e.other["variable"]] = e.other["value"] # require "=" at the end if not expression[-1] == "=": return RiddleSolution(solution="Error", explanation="No = at the end of the expression!") # solve the expression # remove the = and whitespace expression = expression[:-1].strip() for var, val in var_vals.items(): # replace the variables by values expression = expression.replace(var, str(val)) # check the expression if re.match(r"^[0-9+\-*\/ ]+$", expression) is None: return RiddleSolution(solution="Error", explanation="Missing data or faulty expression") try: # using eval is a bad idea, but this is only for demonstration # and expression may only contain "0-9 +-*/" result = eval(expression) except: return RiddleSolution(solution="Error", explanation="Unable to calculate value of expression") # add some noise and invalidate result (for gatekeeper to check) if random.random() > 0.5: print("UPPS UPPS") result += 1 + int(random.random()*9) return RiddleSolution( solution=str(result), explanation="{} = {}".format(expression, result), used_data=used_data ) else: self.stop_response = True # but we will start a nice riddle, we can solve :D self.sub_riddle( riddle=Riddle( context="[Taschenrechner]", question="x * x =" ), data=[ RiddleData( type=RiddleDataType.TEXT, file_plain="./example/x.txt" ) ] ) return RiddleSolution(solution="Error", explanation="No context [Taschenrechner]!") AGENT_CLASSES = [ SimpleSolveAgent ]