diff --git a/.gitignore b/.gitignore index 5ae3c56..afef1e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.wav +*.safetensors config.ini *.egg-info experimental/ diff --git a/README.md b/README.md index 6dd99b6..4324357 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ - **Divide and Conquer**: For big tasks, spins up multiple agents to plan and execute. -- **Tool-Equipped**: From basic search to flight APIs and file exploration, every agent has it's own tools. +- **Tool-Equipped**: From basic search to api and file exploration, every agent has it's own tools. - **Memory**: Remembers what’s useful, your preferences and past sessions conversation. @@ -185,11 +185,11 @@ Here are some example usage: ### Casual -> *Tell me a joke* +> *Tell me about France* -> *Where is flight ABC777 ? my mom is on that plane* +> *What is the meaning of life ?* -> *what is the meaning of life ?* +> *Should I take creatine before or after workout?* After you type your query, agenticSeek will allocate the best agent for the task. diff --git a/main.py b/main.py index 2c2e1d4..d6442c1 100755 --- a/main.py +++ b/main.py @@ -40,6 +40,10 @@ def main(): provider=provider, verbose=False), BrowserAgent(name="Browser", prompt_path="prompts/browser_agent.txt", + provider=provider, verbose=False), + # Planner agent is experimental, might work poorly, especially with model < 32b + PlannerAgent(name="Planner", + prompt_path="prompts/planner_agent.txt", provider=provider, verbose=False) ] diff --git a/media/exemples/planning.png b/media/exemples/planning.png new file mode 100644 index 0000000..14804e3 Binary files /dev/null and b/media/exemples/planning.png differ diff --git a/sources/agents/agent.py b/sources/agents/agent.py index 7e4248f..af7bf4e 100644 --- a/sources/agents/agent.py +++ b/sources/agents/agent.py @@ -122,7 +122,7 @@ class Agent(): "Computing... I recommand you have a coffee while I work.", "Hold on, I’m crunching numbers.", "Working on it, please let me think."] - speech_module.speak(messages[random.randint(0, len(messages)-1)]) + if speech_module: speech_module.speak(messages[random.randint(0, len(messages)-1)]) def get_blocks_result(self) -> list: return self.blocks_result diff --git a/sources/agents/browser_agent.py b/sources/agents/browser_agent.py index 1447a37..0f46956 100644 --- a/sources/agents/browser_agent.py +++ b/sources/agents/browser_agent.py @@ -252,7 +252,7 @@ class BrowserAgent(Agent): continue animate_thinking(f"Navigating to {links[0]}", color="status") - speech_module.speak(f"Navigating to {links[0]}") + if speech_module: speech_module.speak(f"Navigating to {links[0]}") self.browser.go_to(links[0]) self.current_page = links[0] self.search_history.append(links[0]) diff --git a/sources/agents/planner_agent.py b/sources/agents/planner_agent.py index 56b68c0..7e2f072 100644 --- a/sources/agents/planner_agent.py +++ b/sources/agents/planner_agent.py @@ -17,9 +17,9 @@ class PlannerAgent(Agent): } self.tools['json'].tag = "json" self.agents = { - "coder": CoderAgent(model, name, prompt_path, provider), - "file": FileAgent(model, name, prompt_path, provider), - "web": BrowserAgent(model, name, prompt_path, provider) + "coder": CoderAgent(name, "prompts/coder_agent.txt", provider, verbose=False), + "file": FileAgent(name, "prompts/file_agent.txt", provider, verbose=False), + "web": BrowserAgent(name, "prompts/browser_agent.txt", provider, verbose=False) } self.role = { "en": "Research, setup and code", @@ -70,12 +70,28 @@ class PlannerAgent(Agent): """ return prompt + def show_plan(self, json_plan): + agents_tasks = self.parse_agent_tasks(json_plan) + pretty_print(f"--- Plan ---", color="output") + for task_name, task in agents_tasks: + pretty_print(f"{task}", color="output") + pretty_print(f"--- End of Plan ---", color="output") + def process(self, prompt, speech_module) -> str: - self.memory.push('user', prompt) - self.wait_message(speech_module) - animate_thinking("Thinking...", color="status") + ok = False agents_tasks = (None, None) - answer, reasoning = self.llm_request() + while not ok: + self.wait_message(speech_module) + animate_thinking("Thinking...", color="status") + self.memory.push('user', prompt) + answer, _ = self.llm_request() + self.show_plan(answer) + ok_str = input("Is the plan ok? (y/n): ") + if ok_str == 'y': + ok = True + else: + prompt = input("Please reformulate: ") + agents_tasks = self.parse_agent_tasks(answer) if agents_tasks == (None, None): return "Failed to parse the tasks", reasoning @@ -83,16 +99,14 @@ class PlannerAgent(Agent): pretty_print(f"I will {task_name}.", color="info") agent_prompt = self.make_prompt(task['task'], task['need']) pretty_print(f"Assigned agent {task['agent']} to {task_name}", color="info") - speech_module.speak(f"I will {task_name}. I assigned the {task['agent']} agent to the task.") + if speech_module: speech_module.speak(f"I will {task_name}. I assigned the {task['agent']} agent to the task.") try: - self.agents[task['agent'].lower()].process(agent_prompt, None) + self.agents[task['agent'].lower()].process(agent_prompt, speech_module) pretty_print(f"-- Agent answer ---\n\n", color="output") self.agents[task['agent'].lower()].show_answer() pretty_print(f"\n\n", color="output") except Exception as e: - pretty_print(f"Error: {e}", color="failure") - speech_module.speak(f"I encountered an error: {e}") - break + raise e self.last_answer = answer return answer, reasoning