From f1f2fb1397446958d7f57f95d04a7f647734a278 Mon Sep 17 00:00:00 2001 From: Wendong Date: Thu, 22 May 2025 00:35:37 +0800 Subject: [PATCH] update mistral example --- examples/mcp_servers_config.json | 6 +- examples/run_mistral.py | 190 ++++++++++++++++++------------- pyproject.toml | 1 + uv.lock | 18 +++ 4 files changed, 132 insertions(+), 83 deletions(-) diff --git a/examples/mcp_servers_config.json b/examples/mcp_servers_config.json index d94bd91..f2a22ec 100644 --- a/examples/mcp_servers_config.json +++ b/examples/mcp_servers_config.json @@ -2,8 +2,10 @@ "mcpServers": { "playwright": { "command": "npx", - "args": ["-y", "@executeautomation/playwright-mcp-server"] + "args": [ + "@playwright/mcp@latest" + ] } } -} +} diff --git a/examples/run_mistral.py b/examples/run_mistral.py index 5369876..a5e1963 100644 --- a/examples/run_mistral.py +++ b/examples/run_mistral.py @@ -11,25 +11,83 @@ # See the License for the specific language governing permissions and # limitations under the License. # ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. ========= +"""MCP Multi-Agent System Example + +This example demonstrates how to use MCP (Model Context Protocol) with CAMEL agents +for advanced information retrieval and processing tasks. + +Environment Setup: +1. Configure the required dependencies of owl library + Refer to: https://github.com/camel-ai/owl for installation guide + +2. MCP Server Setup: + + + 2.1 MCP Playwright Service: + ```bash + # Install MCP service + npm install -g @executeautomation/playwright-mcp-server + npx playwright install-deps + + # Configure in mcp_servers_config.json: + { + "mcpServers": { + "playwright": { + "command": "npx", + "args": ["-y", "@executeautomation/playwright-mcp-server"] + } + } + } + ``` + + 2.2 MCP Fetch Service (Optional - for better retrieval): + ```bash + # Install MCP service + pip install mcp-server-fetch + + # Configure in mcp_servers_config.json: + { + "mcpServers": { + "fetch": { + "command": "python", + "args": ["-m", "mcp_server_fetch"] + } + } + } + ``` + +Usage: +1. Ensure all MCP servers are properly configured in mcp_servers_config.json +2. Run this script to create a multi-agent system that can: + - Access and manipulate files through MCP Desktop Commander + - Perform web automation tasks using Playwright + - Process and generate information using Mistral + - Fetch web content (if fetch service is configured) +3. The system will execute the specified task while maintaining security through + controlled access + +Note: +- All file operations are restricted to configured directories +- Supports asynchronous operations for efficient processing +""" + +import asyncio import sys -import pathlib +from pathlib import Path +from typing import List + from dotenv import load_dotenv + from camel.models import ModelFactory -from camel.toolkits import ( - AudioAnalysisToolkit, - CodeExecutionToolkit, - ExcelToolkit, - ImageAnalysisToolkit, - SearchToolkit, - VideoAnalysisToolkit, - BrowserToolkit, - FileWriteToolkit, -) +from camel.toolkits import FunctionTool from camel.types import ModelPlatformType, ModelType from camel.logger import set_log_level +from camel.toolkits import MCPToolkit from camel.societies import RolePlaying -from owl.utils import run_society, DocumentProcessingToolkit +from owl.utils.enhanced_role_playing import arun_society + +import pathlib base_dir = pathlib.Path(__file__).parent.parent env_path = base_dir / "owl" / ".env" @@ -38,17 +96,16 @@ load_dotenv(dotenv_path=str(env_path)) set_log_level(level="DEBUG") -def construct_society(question: str) -> RolePlaying: - r"""Construct a society of agents based on Mistral model(s). +async def construct_society( + question: str, + tools: List[FunctionTool], +) -> RolePlaying: + r"""build a multi-agent RolePlaying instance. Args: - question (str): The task or question to be addressed by the society. - - Returns: - RolePlaying: A configured society of agents ready to address the question. + question (str): The question to ask. + tools (List[FunctionTool]): The MCP tools to use. """ - - # Create models for different components models = { "user": ModelFactory.create( model_platform=ModelPlatformType.MISTRAL, @@ -60,63 +117,19 @@ def construct_society(question: str) -> RolePlaying: model_type=ModelType.MISTRAL_LARGE, model_config_dict={"temperature": 0}, ), - "browsing": ModelFactory.create( - model_platform=ModelPlatformType.MISTRAL, - model_type=ModelType.MISTRAL_LARGE, - model_config_dict={"temperature": 0}, - ), - "planning": ModelFactory.create( - model_platform=ModelPlatformType.MISTRAL, - model_type=ModelType.MISTRAL_LARGE, - model_config_dict={"temperature": 0}, - ), - "video": ModelFactory.create( - model_platform=ModelPlatformType.MISTRAL, - model_type=ModelType.MISTRAL_PIXTRAL_12B, - model_config_dict={"temperature": 0}, - ), - "image": ModelFactory.create( - model_platform=ModelPlatformType.MISTRAL, - model_type=ModelType.MISTRAL_PIXTRAL_12B, - model_config_dict={"temperature": 0}, - ), - "document": ModelFactory.create( - model_platform=ModelPlatformType.MISTRAL, - model_type=ModelType.MISTRAL_LARGE, - model_config_dict={"temperature": 0}, - ), } - # Configure toolkits - tools = [ - *BrowserToolkit( - headless=True, - web_agent_model=models["browsing"], - planning_agent_model=models["planning"], - ).get_tools(), - *VideoAnalysisToolkit(model=models["video"]).get_tools(), - *AudioAnalysisToolkit().get_tools(), - *CodeExecutionToolkit(sandbox="subprocess", verbose=True).get_tools(), - *ImageAnalysisToolkit(model=models["image"]).get_tools(), - SearchToolkit().search_duckduckgo, - SearchToolkit().search_google, - SearchToolkit().search_wiki, - *ExcelToolkit().get_tools(), - *DocumentProcessingToolkit(model=models["document"]).get_tools(), - *FileWriteToolkit(output_dir="./").get_tools(), - ] - - # Configure agent roles and parameters user_agent_kwargs = {"model": models["user"]} - assistant_agent_kwargs = {"model": models["assistant"], "tools": tools} + assistant_agent_kwargs = { + "model": models["assistant"], + "tools": tools, + } - # Configure task parameters task_kwargs = { "task_prompt": question, "with_task_specify": False, } - # Create and return the society society = RolePlaying( **task_kwargs, user_role_name="user", @@ -124,25 +137,40 @@ def construct_society(question: str) -> RolePlaying: assistant_role_name="assistant", assistant_agent_kwargs=assistant_agent_kwargs, ) - return society -def main(): - r"""Main function to run the OWL system with an example question.""" - # Default research question - default_task = "Open Brave search, summarize the github stars, fork counts, etc. of camel-ai's camel framework, and write the numbers into a python file using the plot package, save it locally, and run the generated python file. Note: You have been provided with the necessary tools to complete this task." +async def main(): + config_path = Path(__file__).parent / "mcp_servers_config.json" + mcp_toolkit = MCPToolkit(config_path=str(config_path)) - # Override default task if command line argument is provided - task = sys.argv[1] if len(sys.argv) > 1 else default_task + try: + await mcp_toolkit.connect() - # Construct and run the society - society = construct_society(task) - answer, chat_history, token_count = run_society(society) + # Default task + default_task = ( + "I'd like a academic report about Andrew Ng, including " + "his research direction, published papers (At least 3), " + "institutions, etc. You have been provided with tools to do " + "browser operation. Open browser to finish the task." + ) - # Output the result - print(f"\033[94mAnswer: {answer}\033[0m") + # Override default task if command line argument is provided + task = sys.argv[1] if len(sys.argv) > 1 else default_task + + # Connect to all MCP toolkits + tools = [*mcp_toolkit.get_tools()] + society = await construct_society(task, tools) + answer, chat_history, token_count = await arun_society(society) + print(f"\033[94mAnswer: {answer}\033[0m") + + finally: + # Make sure to disconnect safely after all operations are completed. + try: + await mcp_toolkit.disconnect() + except Exception: + print("Disconnect failed") if __name__ == "__main__": - main() + asyncio.run(main()) diff --git a/pyproject.toml b/pyproject.toml index d343c7a..bdcaa21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ dependencies = [ "mcp-server-fetch==2025.1.17", "xmltodict>=0.14.2", "firecrawl>=2.5.3", + "mistralai>=1.7.0", ] [project.urls] diff --git a/uv.lock b/uv.lock index 0b53565..1473b7b 100644 --- a/uv.lock +++ b/uv.lock @@ -1832,6 +1832,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, ] +[[package]] +name = "mistralai" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "eval-type-backport" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "python-dateutil" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/d0/11e0116a02aa88701422ccc048185ed8834754f3b94140bfad09620c9d11/mistralai-1.7.0.tar.gz", hash = "sha256:94e3eb23c1d3ed398a95352062fd8c92993cc3754ed18e9a35b60aa3db0bd103", size = 141981 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/77/eb7519ddfccb6428ac430129e7b42cc662e710cb719f82c0ffe79ab50859/mistralai-1.7.0-py3-none-any.whl", hash = "sha256:e0e75ab8508598d69ae19b14d9d7e905db6259a2de3cf9204946a27e9bf81c5d", size = 301483 }, +] + [[package]] name = "more-itertools" version = "10.7.0" @@ -2389,6 +2405,7 @@ dependencies = [ { name = "gradio" }, { name = "mcp-server-fetch" }, { name = "mcp-simple-arxiv" }, + { name = "mistralai" }, { name = "xmltodict" }, ] @@ -2400,6 +2417,7 @@ requires-dist = [ { name = "gradio", specifier = ">=3.50.2" }, { name = "mcp-server-fetch", specifier = "==2025.1.17" }, { name = "mcp-simple-arxiv", specifier = "==0.2.2" }, + { name = "mistralai", specifier = ">=1.7.0" }, { name = "xmltodict", specifier = ">=0.14.2" }, ]