diff --git a/README.md b/README.md index 0869eb2..d6d9d64 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,10 @@ python3 setup.py install Make sure you have [Ollama](https://ollama.com/) installed. -Download the `deepseek-r1:7b` model from [DeepSeek](https://deepseek.com/models) +Download the `deepseek-r1:14b` model from [DeepSeek](https://deepseek.com/models) ```sh -ollama pull deepseek-r1:7b +ollama pull deepseek-r1:14b ``` ### 2️ **Run the Assistant (Ollama)** @@ -102,15 +102,16 @@ Start the ollama server ollama serve ``` -Change the config.ini file to set the provider_name to `ollama` and provider_model to `deepseek-r1:7b` +Change the config.ini file to set the provider_name to `ollama` and provider_model to `deepseek-r1:14b` -NOTE: `deepseek-r1:7b`is an example, use a bigger model if your hardware allow it. +NOTE: `deepseek-r1:14b`is an example, use a bigger model if your hardware allow it. ```sh [MAIN] is_local = True provider_name = ollama -provider_model = deepseek-r1:7b +provider_model = deepseek-r1:14b +provider_server_address = 127.0.0.1:11434 ``` start all services : @@ -153,7 +154,7 @@ Now on your personal computer: Clone the repository. -Change the `config.ini` file to set the `provider_name` to `server` and `provider_model` to `deepseek-r1:7b`. +Change the `config.ini` file to set the `provider_name` to `server` and `provider_model` to `deepseek-r1:14b`. Set the `provider_server_address` to the ip address of the machine that will run the model. ```sh diff --git a/config.ini b/config.ini index 40f5319..5747b8c 100644 --- a/config.ini +++ b/config.ini @@ -2,10 +2,10 @@ is_local = True provider_name = ollama provider_model = deepseek-r1:14b -provider_server_address = 127.0.0.1:5000 +provider_server_address = 127.0.0.1:11434 agent_name = Friday recover_last_session = True save_session = False speak = True listen = False -work_dir = /Users/mlg/Documents/A-project/AI/Agents/agenticSeek/ai_workplace \ No newline at end of file +work_dir = /Users/mlg/Documents/ai_workplace \ No newline at end of file diff --git a/sources/agents/browser_agent.py b/sources/agents/browser_agent.py index e226a3d..feecb3c 100644 --- a/sources/agents/browser_agent.py +++ b/sources/agents/browser_agent.py @@ -5,6 +5,7 @@ from sources.utility import pretty_print, animate_thinking from sources.agents.agent import Agent from sources.tools.searxSearch import searxSearch from sources.browser import Browser +from datetime import date class BrowserAgent(Agent): def __init__(self, model, name, prompt_path, provider): @@ -15,12 +16,16 @@ class BrowserAgent(Agent): self.tools = { "web_search": searxSearch(), } - self.role = "web search, internet, google" + self.role = "web search, internet browsing, news" self.browser = Browser() self.search_history = [] self.navigable_links = [] self.notes = [] + self.date = self.get_today_date() + def get_today_date(self) -> str: + date_time = date.today() + return date_time.strftime("%B %d, %Y") def extract_links(self, search_result: str): pattern = r'(https?://\S+|www\.\S+)' @@ -90,11 +95,13 @@ class BrowserAgent(Agent): Error: x.com does not discuss anything related to the user’s query and no navigation link are usefull GO_BACK - Example 3 (not useful, no related links): - Note: I found on github.com that the creator of agenticSeek is fosowl. + Example 3 (query answer found): + Note: I found on github.com that agenticSeek is Fosowl. Given this information, given this I should exit the web browser. REQUEST_EXIT + Current date: {self.date} Remember, the user asked: {user_prompt} + Do not exit until you found information the user seek or accomplished the task. """ def llm_decide(self, prompt): @@ -153,12 +160,32 @@ class BrowserAgent(Agent): Summarize the finding, and provide a conclusion that answer the request. """ + + def search_prompt(self, user_prompt): + return f""" + Current date: {self.date} + Make a efficient search engine query to help users with their request: + {user_prompt} + Example: + User: "search: hey jarvis i want you to login to my twitter and say hello everyone " + You: Twitter + + User: "I need info on the best laptops for AI this year." + You: "search: best laptops 2025 to run Machine Learning model, reviews" + + User: "Search for recent news about space missions." + You: "search: Recent space missions news, {self.date}" + + Do not explain, do not write anything beside the search query. + """ def process(self, user_prompt, speech_module) -> str: complete = False animate_thinking(f"Searching...", color="status") - search_result_raw = self.tools["web_search"].execute([user_prompt], False) + self.memory.push('user', self.search_prompt(user_prompt)) + ai_prompt, _ = self.llm_request() + search_result_raw = self.tools["web_search"].execute([ai_prompt], False) search_result = self.jsonify_search_results(search_result_raw)[:5] # until futher improvement prompt = self.make_newsearch_prompt(user_prompt, search_result) unvisited = [None] @@ -188,7 +215,7 @@ class BrowserAgent(Agent): self.browser.close() prompt = self.conclude_prompt(user_prompt) self.memory.push('user', prompt) - answer, reasoning = self.llm_request(prompt) + answer, reasoning = self.llm_request() pretty_print(answer, color="output") return answer, reasoning diff --git a/sources/browser.py b/sources/browser.py index 52025d5..2f11af4 100644 --- a/sources/browser.py +++ b/sources/browser.py @@ -81,7 +81,7 @@ class Browser: """Navigate to a specified URL.""" try: self.driver.get(url) - time.sleep(2) # Wait for page to load + time.sleep(1) # Wait for page to load self.logger.info(f"Navigated to: {url}") return True except WebDriverException as e: diff --git a/sources/interaction.py b/sources/interaction.py index 6a1282a..9c17f2a 100644 --- a/sources/interaction.py +++ b/sources/interaction.py @@ -58,7 +58,7 @@ class Interaction: buffer = "" PROMPT = "\033[1;35m➤➤➤ \033[0m" - while buffer == "" or buffer.isascii() == False: + while not buffer: try: buffer = input(PROMPT) except EOFError: @@ -98,11 +98,11 @@ class Interaction: agent = self.router.select_agent(self.last_query) if agent is None: return - if self.current_agent != agent: - self.current_agent = agent - # get history from previous agent, good ? + if self.current_agent != agent and self.last_answer is not None: + ## get history from previous agent, good ? self.current_agent.memory.push('user', self.last_query) self.current_agent.memory.push('assistant', self.last_answer) + self.current_agent = agent self.last_answer, _ = agent.process(self.last_query, self.speech) def show_answer(self) -> None: diff --git a/sources/llm_provider.py b/sources/llm_provider.py index 7b87415..a510c92 100644 --- a/sources/llm_provider.py +++ b/sources/llm_provider.py @@ -21,15 +21,16 @@ class Provider: "ollama": self.ollama_fn, "server": self.server_fn, "openai": self.openai_fn, - "huggingface": self.huggingface_fn + "huggingface": self.huggingface_fn, + "deepseek-api": self.deepseek_fn } self.api_key = None - self.unsafe_providers = ["openai"] + self.unsafe_providers = ["openai", "deepseek-api"] if self.provider_name not in self.available_providers: raise ValueError(f"Unknown provider: {provider_name}") if self.provider_name in self.unsafe_providers: print("Warning: you are using an API provider. You data will be sent to the cloud.") - self.get_api_key(self.provider_name) + self.api_key = self.get_api_key(self.provider_name) elif self.server != "": print("Provider", provider_name, "initialized at", self.server) self.check_address_format(self.server) @@ -79,6 +80,8 @@ class Provider: """ Check if an IP address is online by sending a ping request. """ + if ip_address == "127.0.0.1": + return True param = '-n' if platform.system().lower() == 'windows' else '-c' command = ['ping', param, '1', ip_address] try: @@ -164,8 +167,7 @@ class Provider: """ Use openai to generate text. """ - api_key = self.get_api_key("openai") - client = OpenAI(api_key=api_key) + client = OpenAI(api_key=self.api_key) try: response = client.chat.completions.create( model=self.model, @@ -178,6 +180,24 @@ class Provider: except Exception as e: raise Exception(f"OpenAI API error: {str(e)}") from e + def deepseek_fn(self, history, verbose=False): + """ + Use deepseek api to generate text. + """ + client = OpenAI(api_key=self.api_key, base_url="https://api.deepseek.com") + try: + response = client.chat.completions.create( + model="deepseek-chat", + messages=history, + stream=False + ) + thought = response.choices[0].message.content + if verbose: + print(thought) + return thought + except Exception as e: + raise Exception(f"Deepseek API error: {str(e)}") from e + def test_fn(self, history, verbose = True): """ This function is used to conduct tests. diff --git a/sources/router.py b/sources/router.py index 2ebd991..f6b27b5 100644 --- a/sources/router.py +++ b/sources/router.py @@ -61,7 +61,7 @@ class AgentRouter: result = self.classify_text(text) for agent in self.agents: if result["labels"][0] == agent.role: - pretty_print(f"Selected agent: {agent.agent_name}", color="warning") + pretty_print(f"Selected agent: {agent.agent_name} (roles: {agent.role})", color="warning") return agent return None