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 execute_post(self, state: State) -> Action: offset_last = state.command.replace(f'{self.LAST_DIRECTIVE_DIRECTIVE}', '').strip() if not offset_last: offset_last = '0' if not offset_last.isdigit(): offset_last = '0' offset_last_as_int = int(offset_last) last_message = self.server_status_datasource.get_last_message(state.user_name, offset=offset_last_as_int) if not last_message: return Action() info_to_show = InfoDebug( command_id=last_message.command_id, user_name=last_message.user_name, command=last_message.command, root=last_message.root, processes=last_message.processes, file_changes=last_message.file_changes, network=last_message.network, result_code=last_message.result_code, stderr=last_message.stderr, already_processed=last_message.already_processed, action_suggested=last_message.action_suggested ) return Action( description=str(info_to_show.json()) )
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 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 process_post(self, command: State, ignore_threshold: bool) -> Optional[Action]: plugin_instances = self.agent_datasource.get_instances( command.user_name) candidate_actions = [] for plugin_instance in plugin_instances: action_post_executed = plugin_instance.post_execute(command) action_post_executed.agent_owner = plugin_instance.agent_name if action_post_executed: candidate_actions.append(action_post_executed) suggested_command = self.select_best_candidate(command, plugin_instances, candidate_actions, ignore_threshold, self._post_exec_id) self.store_post_orchestrator_memory(command, plugin_instances, candidate_actions, ignore_threshold, suggested_command) if not suggested_command: suggested_command = Action() if not suggested_command.suggested_command: suggested_command.suggested_command = command.command return suggested_command
def get_next_action(self, state: State) -> Action: cmd = state.command is_question = self.question_detection_mod.is_question(cmd) if not is_question: return Action(suggested_command=state.command, confidence=0.0) response = None try: response = self.__call_api__(cmd) except Exception: pass if response is None or response['status'] != 'success': return Action(suggested_command=state.command, confidence=0.0) command = response['commands'][-1] confidence = response['dists'][-1] try: cmd_tldr = tldr_wrapper.get_command_tldr(command) except Exception as err: print('Exception: ' + str(err)) cmd_tldr = '' return Action(suggested_command="man {}".format(command), confidence=confidence, description=cmd_tldr)
def process(self, command: State, ignore_threshold: bool, force_agent: str = None) -> Optional[Union[Action, List[Action]]]: if force_agent: plugin_instances = self.agent_datasource.get_instances(command.user_name, force_agent) ignore_threshold = True else: plugin_instances = self.agent_datasource.get_instances(command.user_name) candidate_actions = agent_executor.execute_agents(command, plugin_instances) suggested_command = self.select_best_candidate(command, plugin_instances, candidate_actions, ignore_threshold, self._pre_exec_id) if not suggested_command: suggested_command = Action() self.store_pre_orchestrator_memory(command, plugin_instances, candidate_actions, ignore_threshold, suggested_command) if isinstance(suggested_command, Action): if not suggested_command.suggested_command: suggested_command.suggested_command = command.command else: for action in suggested_command: if not action.suggested_command: action.suggested_command = command.command return suggested_command
def process_post_command(self, message: State) -> Action: message = self.complete_history(message) command_runner = self.command_runner_factory \ .provide_post_command_runner(message.command, self.agent_runner) action = command_runner.execute_post(message) if not action: action = Action() action.origin_command = message.command return action
def post_execute(self, state: State) -> Action: if state.command.startswith('ls') and state.result_code != '0': return Action(description=Colorize() .append(f"Are you sure that this command is correct?({state.result_code})\n") .warning() .append(f"Try man ls for more info ") .to_console(), confidence=1 ) return Action(suggested_command=state.command)
def execute(self, state: State) -> Union[Action, List[Action]]: try: action_to_return = self.get_next_action(state) # pylint: disable=broad-except except: action_to_return = Action() if isinstance(action_to_return, list): for action in action_to_return: action.agent_owner = self.agent_name else: action_to_return.agent_owner = self.agent_name return action_to_return
def post_execute(self, state: State) -> Action: if state.result_code == '0': return Action(suggested_command=state.command) # Summarize output from current state text_to_speak = self.summarize_output(state) # Convert text to audio self.synthesize(text_to_speak) # Play the generated audio self.speak() return Action(suggested_command=NOOP_COMMAND, confidence=0.01)
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 get_next_action(self, state: State) -> Action: # user typed in, in natural language command = state.command try: ## Needs to be a post request since service/endpoint is configured for post endpoint_comeback = requests.post(tellina_endpoint, json={ 'command': command }).json() ## tellina endpoint must return a json with # tellina response, the cmd for the user NL utterance response = 'Try >> ' + endpoint_comeback['response'] # the confidence; the tellina endpoint currently returns 0.0 confidence = float(endpoint_comeback['confidence']) return Action( suggested_command=NOOP_COMMAND, execute=True, description=Colorize().info().append(response).to_console(), confidence=confidence) except Exception as ex: return [{"text": "Method failed with status " + str(ex)}, 0.0]
def ask_user_prompt(command_to_execute: Action) -> Optional[str]: if command_to_execute.is_same_command(): return command_to_execute.origin_command if command_to_execute.execute: return command_to_execute.suggested_command print(Colorize().emoji( Colorize.EMOJI_ROBOT).info().append(" Suggests: ").info().append( f"{command_to_execute.suggested_command} ").append( "(y/n/e)").to_console()) while True: command_input = input() if is_yes_command(command_input): return command_to_execute.suggested_command if is_not_command(command_input): return command_to_execute.origin_command if is_explain_command(command_input): print(Colorize().warning().append( f"Description: {command_to_execute.description}").to_console()) print(Colorize().info().append( 'choose yes[y] or no[n] or explain[e]').to_console())
def get_next_action(self, state: State) -> Action: # user typed in, in natural language command = state.command # truncate to first 1000 chars command = command[:1000] try: response = requests.post(gpt3_endpoint, json={ 'text': command, 'use_cached_prompt': True }).json() response = response['response'] return Action( suggested_command=response, execute=False, description= "Currently GPT-3 does not provide an explanation. Got an idea? Contribute to CLAI!", confidence=0.0) except Exception as ex: return [{"text": "Method failed with status " + str(ex)}, 0.0]
def create_message_list(selected_plugin: List[str], all_plugins: List[AgentDescriptor], verbose_mode=False) -> Action: text = 'Available Skills:\n' for plugin in all_plugins: if plugin.pkg_name in selected_plugin: text += Colorize() \ .emoji(Colorize.EMOJI_CHECK) \ .complete() \ .append(f" {get_printable_name(plugin)}\n") \ .to_console() if verbose_mode: text += Colorize() \ .complete() \ .append(f"{plugin.description}\n") \ .to_console() else: text += \ Colorize() \ .emoji(Colorize.EMOJI_BOX) \ .append(f' {get_printable_name(plugin)}\n') \ .to_console() if verbose_mode: text += Colorize() \ .append(f"{plugin.description}\n") \ .to_console() return Action( suggested_command=':', description=text, execute=True )
def get_set_cluster_config(self): if not self.cluster_name: self.cluster_name = "<enter-cluster-name>" command = 'ibmcloud ks cluster-config {} | grep -e "export" | echo'.format( self.cluster_name) return Action(suggested_command=command, confidence=1.0)
def execute_post(self, state: State) -> Action: if state.result_code == "0" and state.action_suggested.suggested_command != ":": return create_message_list( self.agent_datasource.get_current_plugin_name(state.user_name), self.agent_datasource.all_plugins()) return Action()
def docker_push(self): if not self.namespace: self.namespace = "<enter-namespace>" command = 'docker push us.icr.io/{}/{}:{}'.format( self.namespace, self.name, self.tag) return Action(suggested_command=command, confidence=1.0, execute=False)
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 post_execute(self, state: State) -> Action: # keep track of state changes if state.result_code == '0': # need stdout for state monitoring self.exe.parse_command(state.command, stdout = "") return Action(suggested_command=NOOP_COMMAND)
def _internal_send(self, command_to_send): self.start_connections(self.host, int(self.port)) self.write(command_to_send) action = self.read() if action: return action return Action(origin_command=command_to_send.command, suggested_command=command_to_send.command)
def get_next_action(self, state: State) -> Action: command = state.command for cmd in self.equivalencies: if command.startswith(cmd): return self.__build_suggestion(command, self.equivalencies[cmd], cmd) return Action(suggested_command=NOOP_COMMAND)
def get_next_action(self, state: State) -> Action: command = state.command data, confidence = self.service(command) response = data["text"] return Action( suggested_command=NOOP_COMMAND, execute=True, description=Colorize().info().append(response).to_console(), confidence=confidence)
def execute(self, state: State) -> Action: if not self.server_status_datasource.is_power(): text = 'You have manual mode already enable, use clai auto to activate it' else: self.server_status_datasource.set_power(False) text = 'You have enable the manual mode' return Action(suggested_command=NOOP_COMMAND, origin_command=state.command, description=text, execute=True)
def post_execute(self, state: State) -> Action: if state.result_code == '0': return Action(suggested_command=state.command) cmd = str(state.command) stderr = str(state.stderr) try: # Get corrected command from `thefuck` bot settings.init() cmd = Command(cmd, stderr) cmd_corrected = get_corrected_commands(cmd) cmd_to_run = next(cmd_corrected).script except Exception: return Action(suggested_command=state.command, confidence=0.1) else: return Action(description=Colorize().info().append( "Maybe you want to try: {}".format(cmd_to_run)).to_console(), confidence=0.8)
def execute(self, state: State) -> Action: self.agent_datasource.reload() text = Colorize() \ .complete() \ .append("Plugins reloaded.\n") \ .to_console() return Action(suggested_command=":", execute=True, description=text, origin_command=state.command)
def create_error_install(name: str) -> Action: text = Colorize() \ .warning() \ .append(f"{name} is not a valid skill to add to the catalog. You need to write a folder or a valid url. \n") \ .append("Example: clai install ./my_new_agent") \ .to_console() return Action( suggested_command=':', description=text, execute=True )
def create_error_select(selected_plugin: str) -> Action: text = Colorize() \ .warning() \ .append(f"{selected_plugin} is not a valid skill name. Write >> clai skills to check available skills.") \ .append("Example: >> clai activate nlc2cmd") \ .to_console() return Action( suggested_command=':', description=text, execute=True )
def select_best_candidate(self, command: State, agent_list: List[Agent], candidate_actions: Optional[List[Union[Action, List[Action]]]], force_response: bool, pre_post_state: str) -> Optional[Union[Action, List[Action]]]: agent_names = [agent.agent_name for agent in agent_list] suggested_command = self.orchestrator.choose_action( command=command, agent_names=agent_names, candidate_actions=candidate_actions, force_response=force_response, pre_post_state=pre_post_state) if not suggested_command: suggested_command = Action() return suggested_command