async def manage_messages(self, websocket, path): data = await websocket.recv() logger.info(f" read from the web socket < {data}") action = self.process_message(data) print(f"> {action}") action_to_send = str(action.json()).encode('utf8') await websocket.send(action_to_send)
def get_next_action(self, state: State) -> Action: # to be ultimately replaced by a suitable intent recognizer # refer to the nlc2cmd skill for an example of a NLC layer if state.command in self.intents: # deploy to kube deploys local Dockerfile to your ibmcloud # run Dockerfile brings up an application locally self.exe.set_goal(state.command) # this is the sequence of actions that achieves the user's goal plan = self.exe.get_plan() if plan: logger.info("####### log plan inside ibmcloud ########") logger.info(plan) action_list = [] for action in plan: # translate from actions in the planner's domain to Action Class action_object = self.exe.execute_action(action) # some actions may have null executions (internal to the reasoning engine) if action_object: action_list.append(action_object) return action_list else: return Action(suggested_command=NOOP_COMMAND, execute=True, description=Colorize().info().append('Sorry could not find a plan to help! :-(').to_console(), confidence=1.0) # does not do anything else by default else: return Action(suggested_command=NOOP_COMMAND)
def create_socket(self, host: str, port: int): self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server_socket.bind((host, port)) self.server_socket.listen() logger.info(f"Listening {host} {port}") self.server_socket.setblocking(False)
def __process_command(self, message: State) -> Action: if not message.is_already_processed(): message.previous_execution = self.server_status_datasource.get_last_message(message.user_name) actions = self.__process_command_ai(message) message.mark_as_processed() logger.info(f"after setting info: {message.is_already_processed()}") self.server_status_datasource.store_info(message) action = self.server_pending_actions_datasource.store_pending_actions( message.command_id, actions, message.user_name) else: logger.info(f"we have pending action") action = self.server_pending_actions_datasource.get_next_action(message.command_id, message.user_name) if action is None: action = Action( suggested_command=message.command, origin_command=message.command, execute=False ) action.origin_command = message.command if message.is_post_process(): message.action_post_suggested = action else: message.action_suggested = action self.server_status_datasource.store_info(message) action.execute = action.execute or self.server_status_datasource.is_power() return action
def send(self, message: StateDTO) -> Action: try: return self.connector.send(message) # pylint: disable=broad-except except Exception as exception: logger.info(f"error: {exception}") return Action(origin_command=message.command, suggested_command=message.command)
def execute(self, state: State) -> Action: plugin_to_select = state.command.replace(f'{self.SELECT_DIRECTIVE}', '').strip() plugin_to_select = extract_quoted_agent_name(plugin_to_select) agent_descriptor = self.agent_datasource.get_agent_descriptor( plugin_to_select) plugins_config = self.config_storage.read_config(None) if not agent_descriptor: return create_error_select(plugin_to_select) if agent_descriptor and not agent_descriptor.installed: logger.info( f'installing dependencies of plugin {agent_descriptor.name}') command = f'$CLAI_PATH/fileExist.sh {agent_descriptor.pkg_name} $CLAI_PATH' \ f'{" --user" if plugins_config.user_install else ""}' action_selected_to_return = Action(suggested_command=command, execute=True) else: self.select_plugin(plugin_to_select, state) action_selected_to_return = Action(suggested_command=":", execute=True) action_selected_to_return.origin_command = state.command return action_selected_to_return
def preload_plugins(self): all_descriptors = self.all_plugins() installed_agents = list(filter(lambda value: value.installed, all_descriptors)) for descriptor in installed_agents: self.start_agent(descriptor) logger.info("finish init")
def __service_connection(self, key, mask, process_message): logger.info(f"service connection") fileobj = key.fileobj data = key.data if mask & selectors.EVENT_READ: data = self.__read(data, fileobj, process_message) if mask & selectors.EVENT_WRITE: self.__write(data, fileobj)
def __store__(self, event: StatEvent): if not self.report_enable: return try: logger.info(f"record stats -> {event}") self.queue.put(event) # pylint: disable=broad-except except Exception as err: logger.info(f"error sending: {err}")
def write(self, message: StateDTO): events = self.sel.select(timeout=5) key = events[0][0] client_socket = key.fileobj data = key.data self.sel.modify(client_socket, selectors.EVENT_WRITE, data) logger.info(f'echoing ${data}') data.outb = str(message.json()) sent = client_socket.send(data.outb.encode('utf-8')) data.outb = data.outb[sent:] self.sel.modify(client_socket, selectors.EVENT_READ, data)
def consumer(queue): while True: event = queue.get() if event is None: break logger.info(f"send_event: {event}") __send_event__(event) queue.task_done() logger.info("----STOP CONSUMING-----")
def __read_equivalencies(self): logger.info('####### read equivalencies inside linuss ########') try: with open(self._config_path, 'r') as json_file: equivalencies = json.load(json_file) except Exception as e: logger.debug(f'Linuss Error: {e}') equivalencies = json.load({}) return equivalencies
def send(self, message: StateDTO) -> Action: try: return self._internal_send(message) # pylint: disable=broad-except except Exception as error: logger.info(f"error {error}") logger.info(traceback.format_exc()) return Action(origin_command=message.command, suggested_command=message.command) finally: self.close()
def __send_event__(event: StatEvent): try: amplitude_logger = amplitude.AmplitudeLogger( api_key="cc826565c91ab899168235a2845db189") event_args = { "device_id": event.user, "event_type": event.event_type, "event_properties": event.data } event = amplitude_logger.create_event(**event_args) amplitude_logger.log_event(event) # pylint: disable=broad-except except Exception as ex: logger.info(f"error tracking event {ex}")
def process_message(self, message: State) -> Action: try: message = self.server_status_datasource.store_info(message) if message.is_post_process(): message = self.server_status_datasource.find_message_stored(message.command_id, message.user_name) return self.process_post_command(message) if message.is_command(): return self.__process_command(message) # pylint: disable=broad-except except Exception as ex: logger.info(f"error processing message {ex}") logger.info(traceback.format_exc()) return Action(origin_command=message.command)
def __move_plugin__(dir_to_install: str) -> Action: if dir_to_install.startswith("http") or dir_to_install.startswith( "https"): cmd = f'cd $CLAI_PATH/clai/server/plugins && curl -O {dir_to_install}' return Action(suggested_command=cmd, execute=True) if not os.path.exists(dir_to_install) or not os.path.isdir( dir_to_install): return create_error_install(dir_to_install) plugin_name = dir_to_install.split('/')[-1] logger.info(f"installing plugin name {plugin_name}") cmd = f'cp -R {dir_to_install} $CLAI_PATH/clai/server/plugins' return Action(suggested_command=cmd, execute=True)
def loop(self, process_message: Callable[[bytes], Action]): self.sel.register(self.server_socket, selectors.EVENT_READ, data=None) try: while self.server_status_datasource.running: events = self.sel.select(timeout=None) for key, mask in events: if key.data is None: self.__accept_wrapper(key.fileobj) else: self.__service_connection(key, mask, process_message) self.sel.unregister(self.server_socket) self.server_socket.close() except KeyboardInterrupt: logger.info("caught keyboard interrupt, exiting") finally: logger.info("server closed") self.sel.close()
def load_agent(self, name: str): try: plugin = importlib.import_module( f'clai.server.plugins.{name}.{name}', package=name) for _, class_member in inspect.getmembers(plugin, inspect.isclass): if issubclass(class_member, Agent) and (class_member is not Agent): member = class_member() if not member: member = ClaiIdentity() self.__plugins[name] = member member.init_agent() member.ready = True logger.info(f"{name} is ready") # pylint: disable=broad-except except Exception as ex: logger.info(f'load agent exception: {ex}')
def __read(self, data, server_socket, process_message): recv_data = b'' chewing = True logger.info(f"receiving from client") while chewing: part = server_socket.recv(self.BUFFER_SIZE) recv_data += part if len(part) < self.BUFFER_SIZE: chewing = False if recv_data: logger.info(f"receiving from client ${recv_data}") action = process_message(recv_data) data.outb = str(action.json()).encode('utf8') else: self.sel.unregister(server_socket) server_socket.close() return data
def all_plugins(self) -> List[AgentDescriptor]: agent_descriptors = list( self.load_descriptors(os.path.join(importer.path, name), name) for importer, name, _ in pkg.iter_modules(self.get_path())) agent_descriptors = self.filter_by_platform(agent_descriptors) plugins_installed = self.config_storage.load_installed() for agent_descriptor in agent_descriptors: agent_descriptor.installed = agent_descriptor.name in plugins_installed logger.info(f"agents runned: {self.__plugins}") for agent_descriptor in agent_descriptors: if agent_descriptor.pkg_name in self.__plugins: logger.info( f"{agent_descriptor.pkg_name} is {self.__plugins[agent_descriptor.pkg_name].ready}" ) agent_descriptor.ready = self.__plugins[ agent_descriptor.pkg_name].ready else: logger.info(f"{agent_descriptor.pkg_name} not iniciate.") agent_descriptor.ready = False return agent_descriptors
def store(self, message: TerminalReplayMemory): if not self.report_enable: return try: command = message.command message_as_json = TerminalReplayMemoryApi( command=self.__parse_state__(command, self.anonymizer), agent_names=message.agent_names, candidate_actions=self.__parse_actions__( message.candidate_actions), force_response=str(message.force_response), suggested_command=self.__parse_actions__( message.suggested_command), ) logger.info(f"store -> {message.command.command_id}") message_to_send = RecordToSendApi(bashbot_info=message_as_json) self.queue.put(message_to_send.json()) # pylint: disable=broad-except except Exception as err: logger.info(f"error sending: {err}")
def get_next_action(self, command_id: str, user_name: str) -> Action: logger.info(f"next command for: {command_id}") actions_by_user = self.__find_pending_actions_by_user(user_name) logger.info(f"find: {actions_by_user}") pending_actions = next( filter(lambda x: x.command_id == command_id, actions_by_user), None) logger.info(f"next actions: {pending_actions}") return pending_actions.next()
def get_next_action(self, state: State) -> Union[Action, List[Action]]: logger.info("This is my agent") if state.command == 'ls': return Action(suggested_command="ls -la", description="This is a demo sample that helps to execute the command in better way.", confidence=1 ) if state.command == 'pwd': return [Action(suggested_command="ls -la", description="This is a demo sample that helps to execute the command in better way.", confidence=1 ), Action(suggested_command="pwd -P", description="This is a demo sample that helps to execute the command in better way.", confidence=1 ) ] if state.previous_execution and state.previous_execution.command == 'ls -4': return Action(suggested_command="ls -a", execute=True, confidence=1) return Action(suggested_command=state.command)
def consumer(queue): while True: data = queue.get() if data is None: break logger.info(f"consume: {data}") headers = {'Content-type': 'application/json'} response = requests.post(url=URL_SERVER, data=data, headers=headers) logger.info(f"[Sent] {response.status_code} message {response.text}") queue.task_done() logger.info("----STOP CONSUMING-----")
def get_next_action(self, state: State) -> Action: logger.info( "================== In HowDoI Bot:get_next_action ========================" ) logger.info("User Command: {}".format(state.command)) # Query data store to find closest matching forum forum = self.store.search(state.command, service='stack_exchange', size=1) if forum: # Find closes match b/w relevant forum for unix logger.info("Success!!! Found relevant forums.") # Find closes match b/w relevant forum and manpages for unix manpages = self.store.search(forum[0]['Answer'], service='manpages', size=5) if manpages: logger.info("Success!!! found relevant manpages.") command = manpages['commands'][-1] confidence = manpages['dists'][-1] logger.info("Command: {} \t Confidence:{}".format( command, confidence)) return Action( suggested_command="man {}".format(command), description=Colorize().emoji(Colorize.EMOJI_ROBOT).append( f"I did little bit of internet searching for you.\n"). info().append("Post: {}\n".format( forum[0]['Content'][:384] + " ...")).append("Answer: {}\n".format( forum[0]['Answer'][:256] + " ...")).append( "Link: {}\n\n".format( forum[0]['Url'])).warning().append( "Do you want to try: man {}".format( command)).to_console(), confidence=confidence) else: logger.info("Failure: Manpage search") logger.info( "============================================================================" ) return Action( suggested_command=NOOP_COMMAND, description=Colorize().emoji(Colorize.EMOJI_ROBOT).append( f"Sorry. It looks like you have stumbled across a problem that even internet has not answer to.\n" ).info().append( f"Have you tried turning it OFF and ON again. ;)"). to_console(), confidence=0.0) else: logger.info("Failure: Forum search") logger.info( "============================================================================" ) return Action( suggested_command=NOOP_COMMAND, description=Colorize().emoji(Colorize.EMOJI_ROBOT).append( f"Sorry. It looks like you have stumbled across a problem that even internet has not answer to.\n" ).warning().append( f"Have you tried turning it OFF and ON again. ;)"). to_console(), confidence=0.0)
def post_execute(self, state: State) -> Action: logger.info( "=========================== In Helpme Bot:post_execute ===================================" ) logger.info( "State:\n Command: {}\n Error Code: {}\n Stderr: {}".format( state.command, state.result_code, state.stderr)) logger.info( "============================================================================" ) if state.result_code != '0': # Query data store to find closest matching forum forum = self.store.search(state.stderr, service='stack_exchange', size=1) if forum: logger.info("Success!!! Found relevant forums.") # Find closes match b/w relevant forum and manpages for unix manpages = self.store.search(forum[0]['Answer'], service='manpages', size=5) if manpages: logger.info("Success!!! found relevant manpages.") command = manpages['commands'][-1] confidence = manpages['dists'][-1] # FIXME: Artificially boosted confidence confidence = 1.0 logger.info("Command: {} \t Confidence:{}".format( command, confidence)) return Action( suggested_command="man {}".format(command), description=Colorize( ).emoji(Colorize.EMOJI_ROBOT).append( f"I did little bit of internet searching for you.\n" ).info().append("Post: {}\n".format( forum[0]['Content'][:384] + " ...")).append("Answer: {}\n".format( forum[0]['Answer'][:256] + " ...")).append("Link: {}\n\n".format( forum[0]['Url'])).warning().append( "Do you want to try: man {}".format( command)).to_console(), confidence=confidence) else: logger.info("Failure: Manpage search") logger.info( "============================================================================" ) return Action( suggested_command=NOOP_COMMAND, description=Colorize( ).emoji(Colorize.EMOJI_ROBOT).append( f"Sorry. It looks like you have stumbled across a problem that even internet doesn't have answer to.\n" ).info().append( f"Have you tried turning it OFF and ON again. ;)"). to_console(), confidence=0.0) else: logger.info("Failure: Forum search") logger.info( "============================================================================" ) return Action( suggested_command=NOOP_COMMAND, description=Colorize().emoji(Colorize.EMOJI_ROBOT).append( f"Sorry. It looks like you have stumbled across a problem that even internet doesn't have answer to.\n" ).warning().append( f"Have you tried turning it OFF and ON again. ;)"). to_console(), confidence=0.0) return Action(suggested_command=state.command)
def __log_info__(self, message): logger.info(f"{self.name}: {message}")
def __write(data, server_socket): if data.outb: logger.info(f"sending from client ${data.outb}") server_socket.send(data.outb) data.outb = b''
def start(self, agent_datasource: AgentDatasource): logger.info(f"-Start tracker-") self.report_enable = agent_datasource.get_report_enable() if self.report_enable: self.consumer_stats = self.pool.map_async(self.consumer, (self.queue, ))
def execute(self, state: State) -> Action: dir_to_install = state.command.replace( f'{self.INSTALL_PLUGIN_DIRECTIVE}', '').strip() logger.info(f'trying to install ${dir_to_install}') return self.__move_plugin__(dir_to_install)