code: from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser
  from langchain.prompts import StringPromptTemplate
  from langchain import OpenAI, SerpAPIWrapper, LLMChain
  from typing import List, Union
  from langchain.schema import AgentAction, AgentFinish
  import re
  from langchain.utilities import BashProcess
  from langchain.tools.human.tool import HumanInputRun
  from langchain_tools.cwtool import CloudWatchInsightQuery
  import sys
  
  # Set up a prompt template
  class CustomPromptTemplate(StringPromptTemplate):
      # The template to use
      template: str
      # The list of tools available
      tools: List[Tool]
      
      def format(self, **kwargs) -> str:
          # Get the intermediate steps (AgentAction, Observation tuples)
          # Format them in a particular way
          intermediate_steps = kwargs.pop("intermediate_steps")
          thoughts = ""
          for action, observation in intermediate_steps:
              thoughts += action.log
              thoughts += f"\nObservation: {observation}\nThought: "
          # Set the agent_scratchpad variable to that value
          kwargs["agent_scratchpad"] = thoughts
          # Create a tools variable from the list of tools provided
          kwargs["tools"] = "\n".join([f"{tool.name}: {tool.description}" for tool in self.tools])
          # Create a list of tool names for the tools provided
          kwargs["tool_names"] = ", ".join([tool.name for tool in self.tools])
          return self.template.format(**kwargs)
  
  class CustomOutputParser(AgentOutputParser):
      
      def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:
          # Check if agent should finish
          if "Final Answer:" in llm_output:
              return AgentFinish(
                  # Return values is generally always a dictionary with a single `output` key
                  # It is not recommended to try anything else at the moment :)
                  return_values={"output": llm_output.split("Final Answer:")[-1].strip()},
                  log=llm_output,
              )
          # Parse out the action and action input
          regex = r"Action: (.*?)[\n]*Action Input:[\s]*(.*)"
          match = re.search(regex, llm_output, re.DOTALL)
          if not match:
              raise ValueError(f"Could not parse LLM output: `{llm_output}`")
          action = match.group(1).strip()
          action_input = match.group(2)
          # Return the action and action input
          return AgentAction(tool=action, tool_input=action_input.strip(" ").strip('"'), log=llm_output)
  
  def agent_run(user_input) -> None:
  
      # Define which tools the agent can use to answer user queries
      search = SerpAPIWrapper()
      bash = BashProcess()
      human = HumanInputRun()
      cloudwatch = CloudWatchInsightQuery()
  
      tools = [
          Tool(
              name = "Search",
              func=search.run,
              description="useful for when you need to answer questions about current events"
          ),
          Tool(
              name = "human",
              func=human.run,
              description="useful for when you need to ask the human for input"
          ),
          Tool(
              name = "cloudwatch",
              func=cloudwatch.run,
              description="useful for when you need run an AWS cloudwatch insight query or search logs in AWS"
          ),
          Tool(
              name = "terminal",
              func=bash.run,
              description="useful for when you need to run commands in a terminal"
          )
      ]
  
      # Set up the base template
      template = """You are a cyber Security professional. You will take steps to achieve the requested task. You have access to the following tools:
      {tools}
  
      Use the following format:
  
      Question: the input question you must answer
      Thought: you should always think about what to do
      Action: the action to take, should be one of [{tool_names}]
      Action Input: the input to the action
      Observation: the result of the action
      ... (this Thought/Action/Action Input/Observation can repeat N times)
      Thought: I now know the final answer
      Final Answer: the final answer to the original input question
  
      Question: {input}
      {agent_scratchpad}"""
  
      prompt = CustomPromptTemplate(template=template,tools=tools,input_variables=["input", "intermediate_steps"])
      output_parser = CustomOutputParser()
      llm = OpenAI(temperature=0)
      llm_chain = LLMChain(llm=llm, prompt=prompt)
  
      tool_names = [tool.name for tool in tools]
      agent = LLMSingleActionAgent(
          llm_chain=llm_chain, 
          output_parser=output_parser,
          stop=["\nObservation:"], 
          allowed_tools=tool_names
      )
  
      agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
      agent_executor.run(user_input)
  
apis: langchain.tools.human.tool.HumanInputRun langchain_tools.cwtool.CloudWatchInsightQuery langchain.agents.AgentExecutor.from_agent_and_tools langchain.agents.LLMSingleActionAgent langchain.utilities.BashProcess langchain.SerpAPIWrapper langchain.LLMChain langchain.OpenAI langchain.agents.Tool
extract_api: [((2630, 2646), 'langchain.SerpAPIWrapper', 'SerpAPIWrapper', ([], {}), '()\n', (2644, 2646), False, 'from langchain import OpenAI, SerpAPIWrapper, LLMChain\n'), ((2658, 2671), 'langchain.utilities.BashProcess', 'BashProcess', ([], {}), '()\n', (2669, 2671), False, 'from langchain.utilities import BashProcess\n'), ((2684, 2699), 'langchain.tools.human.tool.HumanInputRun', 'HumanInputRun', ([], {}), '()\n', (2697, 2699), False, 'from langchain.tools.human.tool import HumanInputRun\n'), ((2717, 2741), 'langchain_tools.cwtool.CloudWatchInsightQuery', 'CloudWatchInsightQuery', ([], {}), '()\n', (2739, 2741), False, 'from langchain_tools.cwtool import CloudWatchInsightQuery\n'), ((4330, 4351), 'langchain.OpenAI', 'OpenAI', ([], {'temperature': '(0)'}), '(temperature=0)\n', (4336, 4351), False, 'from langchain import OpenAI, SerpAPIWrapper, LLMChain\n'), ((4368, 4400), 'langchain.LLMChain', 'LLMChain', ([], {'llm': 'llm', 'prompt': 'prompt'}), '(llm=llm, prompt=prompt)\n', (4376, 4400), False, 'from langchain import OpenAI, SerpAPIWrapper, LLMChain\n'), ((4461, 4587), 'langchain.agents.LLMSingleActionAgent', 'LLMSingleActionAgent', ([], {'llm_chain': 'llm_chain', 'output_parser': 'output_parser', 'stop': "['\\nObservation:']", 'allowed_tools': 'tool_names'}), "(llm_chain=llm_chain, output_parser=output_parser, stop\n    =['\\nObservation:'], allowed_tools=tool_names)\n", (4481, 4587), False, 'from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n'), ((4645, 4719), 'langchain.agents.AgentExecutor.from_agent_and_tools', 'AgentExecutor.from_agent_and_tools', ([], {'agent': 'agent', 'tools': 'tools', 'verbose': '(True)'}), '(agent=agent, tools=tools, verbose=True)\n', (4679, 4719), False, 'from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n'), ((2150, 2189), 're.search', 're.search', (['regex', 'llm_output', 're.DOTALL'], {}), '(regex, llm_output, re.DOTALL)\n', (2159, 2189), False, 'import re\n'), ((2765, 2887), 'langchain.agents.Tool', 'Tool', ([], {'name': '"""Search"""', 'func': 'search.run', 'description': '"""useful for when you need to answer questions about current events"""'}), "(name='Search', func=search.run, description=\n    'useful for when you need to answer questions about current events')\n", (2769, 2887), False, 'from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n'), ((2940, 3046), 'langchain.agents.Tool', 'Tool', ([], {'name': '"""human"""', 'func': 'human.run', 'description': '"""useful for when you need to ask the human for input"""'}), "(name='human', func=human.run, description=\n    'useful for when you need to ask the human for input')\n", (2944, 3046), False, 'from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n'), ((3099, 3251), 'langchain.agents.Tool', 'Tool', ([], {'name': '"""cloudwatch"""', 'func': 'cloudwatch.run', 'description': '"""useful for when you need run an AWS cloudwatch insight query or search logs in AWS"""'}), "(name='cloudwatch', func=cloudwatch.run, description=\n    'useful for when you need run an AWS cloudwatch insight query or search logs in AWS'\n    )\n", (3103, 3251), False, 'from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n'), ((3299, 3410), 'langchain.agents.Tool', 'Tool', ([], {'name': '"""terminal"""', 'func': 'bash.run', 'description': '"""useful for when you need to run commands in a terminal"""'}), "(name='terminal', func=bash.run, description=\n    'useful for when you need to run commands in a terminal')\n", (3303, 3410), False, 'from langchain.agents import Tool, AgentExecutor, LLMSingleActionAgent, AgentOutputParser\n')]