diff --git a/docs/using_cli.md b/docs/using_cli.md index b8e9600..f3e2f0f 100644 --- a/docs/using_cli.md +++ b/docs/using_cli.md @@ -56,10 +56,17 @@ To learn more about how the CLI and agents can be scaled and managed in a distri To start the Wise Agents CLI, run the script from your terminal: ```bash -python src/wiseagents/cli/wise_agent_cli.py [path_to_agents_file.yaml] -``` +python src/wiseagents/cli/wise_agent_cli.py --help +usage: Wise Agent Argument Parser [-h] [--debug DEBUG] [filename] + +Wise Agent CLI to run and manage Wise Agents + +positional arguments: + filename is optional. If provided, the CLI will automatically load agents from the specified YAML file upon startup. -- The `[path_to_agents_file.yaml]` is optional. If provided, the CLI will automatically load agents from the specified YAML file upon startup. +options: + -h, --help show this help message and exit + --debug DEBUG Setting the logging level to DEBUG instead of INFO --- diff --git a/src/wiseagents/agents/assistant.py b/src/wiseagents/agents/assistant.py index 5fefa72..0ea4dfb 100644 --- a/src/wiseagents/agents/assistant.py +++ b/src/wiseagents/agents/assistant.py @@ -81,14 +81,14 @@ def process_request(self, request: WiseAgentMessage, Optional[str]: the response to the request message as a string or None if there is no string response yet """ - print(f"AssistantAgent: process_request: {request}") + logging.getLogger(self.name).info(f"AssistantAgent: process_request: {request}") WiseAgentRegistry.get_context(request.context_name).append_chat_completion({"role": "user", "content": request.message}) self.send_request(request, self.destination_agent_name) return None def process_response(self, response : WiseAgentMessage): """Process a response message just sending it back to the client.""" - print(f"AssistantAgent: process_response: {response}") + logging.getLogger(self.name).info(f"AssistantAgent: process_response: {response}") with self._cond: self._response = response self._cond.notify() diff --git a/src/wiseagents/agents/rag_wise_agents.py b/src/wiseagents/agents/rag_wise_agents.py index e57d887..c86e1af 100644 --- a/src/wiseagents/agents/rag_wise_agents.py +++ b/src/wiseagents/agents/rag_wise_agents.py @@ -90,7 +90,7 @@ def process_request(self, request: WiseAgentMessage, conversation_history: List[ Optional[str]: the response to the request message as a string or None if there is no string response yet """ - print(f"[{self.name}] Received a message from {request.sender}. Starting to process it using RAG") + logging.getLogger(self.name).info(f"Received a message from {request.sender}. Starting to process it using RAG") retrieved_documents = retrieve_documents_for_rag(request.message, self.vector_db, self.collection_name, self.k) llm_response_with_sources = create_and_process_rag_prompt(retrieved_documents, request.message, self.llm, self.include_sources, conversation_history, @@ -197,7 +197,7 @@ def process_request(self, request: WiseAgentMessage, conversation_history: List[ Optional[str]: the response to the request message as a string or None if there is no string response yet """ - print(f"[{self.name}] Received a message from {request.sender}. Starting to process it using Graph RAG") + logging.getLogger(self.name).info(f"Received a message from {request.sender}. Starting to process it using Graph RAG") retrieved_documents = retrieve_documents_for_graph_rag(request.message, self.graph_db, self.k, self.retrieval_query, self.params, self.metadata_filter) llm_response_with_sources = create_and_process_rag_prompt(retrieved_documents, request.message, self.llm, self.include_sources, @@ -471,7 +471,7 @@ def process_request(self, request: WiseAgentMessage, conversation_history: List[ Returns: str: the response to the request message as a string """ - print(f"[{self.name}] Received a message from {request.sender}. Starting to challenge it") + logging.getLogger(self.name).info(f"Received a message from {request.sender}. Starting to challenge it") llm_response = self.create_and_process_chain_of_verification_prompts(request.message, conversation_history) return llm_response @@ -566,7 +566,7 @@ def process_request(self, request: WiseAgentMessage, conversation_history: List[ Returns: str: the response to the request message as a string """ - print(f"[{self.name}] Received a message from {request.sender}. Starting to challenge it") + logging.getLogger(self.name).info(f"Received a message from {request.sender}. Starting to challenge it") llm_response = self.create_and_process_chain_of_verification_prompts(request.message, conversation_history) return llm_response diff --git a/src/wiseagents/agents/utility_wise_agents.py b/src/wiseagents/agents/utility_wise_agents.py index 3c64bbe..c30704c 100644 --- a/src/wiseagents/agents/utility_wise_agents.py +++ b/src/wiseagents/agents/utility_wise_agents.py @@ -293,7 +293,7 @@ def process_response(self, response : WiseAgentMessage): Args: response (WiseAgentMessage): the response message to process """ - print(f"Response received: {response}") + logging.getLogger(self.name).info(f"Response received: {response}") ctx = WiseAgentRegistry.get_context(response.context_name) ctx.append_chat_completion(messages= { @@ -309,7 +309,7 @@ def process_response(self, response : WiseAgentMessage): llm_response = self.llm.process_chat_completion(ctx.llm_chat_completion, ctx.llm_available_tools_in_chat) response_message = llm_response.choices[0].message - logging.debug(f"sending response {response_message.content} to: {response.route_response_to}") + logging.getLogger(self.name).info(f"sending response {response_message.content} to: {response.route_response_to}") parent_context = WiseAgentRegistry.remove_context(context_name=response.context_name, merge_chat_to_parent=True) self.send_response(WiseAgentMessage(message=response_message.content, sender=self.name, context_name=parent_context.name), response.route_response_to ) return True diff --git a/src/wiseagents/cli/wise_agent_cli.py b/src/wiseagents/cli/wise_agent_cli.py index 7bf3f53..9143468 100644 --- a/src/wiseagents/cli/wise_agent_cli.py +++ b/src/wiseagents/cli/wise_agent_cli.py @@ -1,4 +1,6 @@ +import argparse import importlib +import logging import signal import sys import threading @@ -47,12 +49,31 @@ def main(): file_path = None default_file_path = "src/wiseagents/cli/test-multiple.yaml" + parser = argparse.ArgumentParser(prog="Wise Agent Argument Parser", description="Wise Agent CLI to run and manage Wise Agents", add_help=True) + parser.add_argument("filename", nargs="?", help="is optional. If provided, the CLI will automatically load agents from the specified YAML file upon startup.") + parser.add_argument("--debug", dest="debug", help="Setting the logging level to DEBUG instead of INFO", type=bool, default=False) + args = parser.parse_args() + logger = logging.getLogger(__name__) + if (args.debug): + level=logging.DEBUG + else: + level=logging.INFO + logging.basicConfig(filename='./log/agents.log', filemode="w", + format='%(asctime)s %(levelname)s [%(name)s]: %(message)s', encoding='utf-8', + level=level) + logging.getLogger("urllib3.connectionpool").setLevel(logging.INFO) + + logger.info(f"Starting CLI in debug mode {args.debug} with file {args.filename}") signal.signal(signal.SIGINT, signal_handler) context_name = "CLI." + str(uuid.uuid4()) WiseAgentRegistry.create_context(context_name) - if (sys.argv.__len__() > 1): - user_input="/load-agents" - file_path=sys.argv[1] + if (args.filename is not None): + user_input="/load-agents" + file_path=args.filename + logger.info(f"Loading agents from {file_path}") + else: + logger.info(f"No agent from {file_path}") + while True: if (user_input == '/help' or user_input == '/h'): print('/(l)oad-agents: Load agents from file') @@ -69,7 +90,7 @@ def main(): print(msg) if (user_input == '/exit' or user_input == '/x'): #stop all agents - print('/exit seceleted! Please wait for the agents to stop') + print('/exit selected! Please wait for the agents to stop') for agent in agent_list: print(f"Stopping agent {agent.name}") agent.stop_agent() @@ -89,11 +110,11 @@ def main(): if not file_path: file_path = default_file_path with open(file_path) as stream: - try: + try: for agent in yaml.load_all(stream, Loader=WiseAgentsLoader): agent : WiseAgent - print(f'Loaded agent: {agent.name}') + logger.info(f'Loaded agent: {agent.name}') if agent.name == "PassThroughClientAgent1": _passThroughClientAgent1 = agent _passThroughClientAgent1.set_response_delivery(response_delivered) @@ -101,7 +122,8 @@ def main(): agent_list.append(agent) except yaml.YAMLError as exc: traceback.print_exc() - print(f"registered agents= {WiseAgentRegistry.fetch_agents_metadata_dict()}") + lines = [f'{key} {value}' for key, value in WiseAgentRegistry.fetch_agents_metadata_dict().items()] + print(f"registered agents=\n {'\n'.join(lines)}") if (user_input == '/chat' or user_input == '/c'): while True: user_input = input("Enter a message (or /back): ") @@ -111,7 +133,8 @@ def main(): _passThroughClientAgent1.send_request(WiseAgentMessage(message=user_input, sender="PassThroughClientAgent1", context_name=context_name), "LLMOnlyWiseAgent2") cond.wait() if (user_input == '/agents' or user_input == '/a'): - print(f"registered agents= {WiseAgentRegistry.fetch_agents_metadata_dict()}") + lines = [f'{key} {value}' for key, value in WiseAgentRegistry.fetch_agents_metadata_dict().items()] + print(f"registered agents=\n {'\n'.join(lines)}") if (user_input == '/send' or user_input == '/s'): agent_name = input("Enter the agent name: ") diff --git a/src/wiseagents/core.py b/src/wiseagents/core.py index e345f71..38888df 100644 --- a/src/wiseagents/core.py +++ b/src/wiseagents/core.py @@ -745,6 +745,9 @@ def __init__(self, name: str, metadata: WiseAgentMetaData, transport: WiseAgentT self.start_agent() def start_agent(self): + if self._llm is not None: + self._llm.set_agent_name(self._name) + ''' Start the agent by setting the call backs and starting the transport.''' self.transport.set_call_backs(self.handle_request, self.process_event, self.process_error, self.process_response) diff --git a/src/wiseagents/llm/openai_API_wise_agent_LLM.py b/src/wiseagents/llm/openai_API_wise_agent_LLM.py index 5116f27..137bb34 100644 --- a/src/wiseagents/llm/openai_API_wise_agent_LLM.py +++ b/src/wiseagents/llm/openai_API_wise_agent_LLM.py @@ -1,3 +1,4 @@ +import logging from typing import Dict, Iterable, Optional import openai @@ -52,7 +53,7 @@ def __getstate__(self) -> object: def connect(self): '''Connect to the remote machine.''' - print(f"Connecting to WiseAgentLLM on remote machine at {self.remote_address} with API key {self.api_key}") + logging.getLogger(__name__).info(f"Connecting to {self._agent_name} on remote machine at {self.remote_address} with API key ***********") self.client = openai.OpenAI(base_url=self.remote_address, api_key=self.api_key) @@ -63,7 +64,7 @@ def process_single_prompt(self, prompt): Args: prompt (str): the prompt to process''' - print(f"Executing WiseAgentLLM on remote machine at {self.remote_address}") + logging.getLogger(__name__).info(f"Executing {self._agent_name} on remote machine at {self.remote_address}") if (self.client is None): self.connect() messages = [] @@ -92,7 +93,7 @@ def process_chat_completion(self, Returns: ChatCompletion: the chat completion result''' - print(f"Executing WiseAgentLLM on remote machine at {self.remote_address}") + logging.getLogger(__name__).info(f"Executing {self._agent_name} on remote machine at {self.remote_address}") if (self.client is None): self.connect() #messages = [] diff --git a/src/wiseagents/llm/wise_agent_LLM.py b/src/wiseagents/llm/wise_agent_LLM.py index 26bdb80..5b207f7 100644 --- a/src/wiseagents/llm/wise_agent_LLM.py +++ b/src/wiseagents/llm/wise_agent_LLM.py @@ -34,7 +34,11 @@ def system_message(self) -> Optional[str]: @property def model_name(self): '''Get the model name.''' - return self._model_name + return self._model_name + + + def set_agent_name(self, agent_name: str) : + self._agent_name = agent_name @abstractmethod def process_single_prompt(self, prompt): diff --git a/src/wiseagents/transports/stomp.py b/src/wiseagents/transports/stomp.py index 400cfa4..a014b9a 100644 --- a/src/wiseagents/transports/stomp.py +++ b/src/wiseagents/transports/stomp.py @@ -112,7 +112,7 @@ def send_request(self, message: WiseAgentMessage, dest_agent_name: str): if self.response_conn.is_connected() == False: self.response_conn.connect(os.getenv("STOMP_USER"), os.getenv("STOMP_PASSWORD"), wait=True) request_destination = '/queue/request/' + dest_agent_name - logging.debug(f"Sending request {message} to {request_destination}") + logging.getLogger(__name__).debug(f"Sending request {message} to {request_destination}") self.request_conn.send(body=yaml.dump(message), destination=request_destination) def send_response(self, message: WiseAgentMessage, dest_agent_name: str): diff --git a/src/wiseagents/wise_agent_messaging.py b/src/wiseagents/wise_agent_messaging.py index ceb4424..09760ed 100644 --- a/src/wiseagents/wise_agent_messaging.py +++ b/src/wiseagents/wise_agent_messaging.py @@ -56,7 +56,7 @@ def __setstate__(self, state): self._message = state["_message"] self._sender = state["_sender"] if state["_message_type"] is not None and state["_message_type"] != "": - logging.debug(f"__setstate__ state[_message_type]: {state['_message_type']}") + logging.getLogger(__name__).debug(f"__setstate__ state[_message_type]: {state['_message_type']}") self._message_type = WiseAgentMessageType(state["_message_type"]) else: self._message_type = None