diff --git a/playground/agents/multion_agent.py b/playground/agents/multion_agent.py index 88e383b3..a6f2ce24 100644 --- a/playground/agents/multion_agent.py +++ b/playground/agents/multion_agent.py @@ -1,12 +1,10 @@ from swarms.agents.multion_agent import MultiOnAgent -from swarms.structs.agent import Agent -from swarms.structs.concurrent_workflow import ConcurrentWorkflow -from swarms.structs.task import Task +import timeit +from swarms import Agent, ConcurrentWorkflow, Task +from swarms.utils.loguru_logger import logger # model -model = MultiOnAgent( - multion_api_key="" -) +model = MultiOnAgent(multion_api_key="") # out = model.run("search for a recipe") agent = Agent( @@ -17,6 +15,7 @@ agent = Agent( system_prompt=None, ) +logger.info("[Agent][ID][MultiOnAgent][Initialized][Successfully") # Task task = Task( @@ -27,16 +26,25 @@ task = Task( ), ) - # Swarm +logger.info( + f"Running concurrent workflow with task: {task.description}" +) + +# Measure execution time +start_time = timeit.default_timer() + workflow = ConcurrentWorkflow( - max_workers=21, + max_workers=1, autosave=True, print_results=True, return_results=True, ) - # Add task to workflow workflow.add(task) workflow.run() + +# Calculate execution time +execution_time = timeit.default_timer() - start_time +logger.info(f"Execution time: {execution_time} seconds") diff --git a/playground/structs/kyle_hackathon.py b/playground/structs/kyle_hackathon.py index c66de68b..48c15b39 100644 --- a/playground/structs/kyle_hackathon.py +++ b/playground/structs/kyle_hackathon.py @@ -37,7 +37,9 @@ def multion_tool( # Execute the interpreter tool @tool -def execute_interpreter_tool(code: str,): +def execute_interpreter_tool( + code: str, +): """ Executes a single command using the interpreter. diff --git a/pyproject.toml b/pyproject.toml index e9af9b9b..00b4ae20 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "swarms" -version = "4.1.8" +version = "4.1.9" description = "Swarms - Pytorch" license = "MIT" authors = ["Kye Gomez "] diff --git a/runtime/multi_threading.rs b/runtime/multi_threading.rs index 99346ed2..0e75606f 100644 --- a/runtime/multi_threading.rs +++ b/runtime/multi_threading.rs @@ -29,48 +29,51 @@ fn my_module(py: Python, m: &PyModule) -> PyResult<()> { Ok(()) } + + +/// The function returns `Ok(())` if all modules are processed successfully. +/// Note: This code assumes that the necessary dependencies (`pyo3`, `rayon`, `log`) are already imported and initialized. +/// +/// # Arguments +/// +/// * `modules` - A vector of `PythonModule` structs representing the Python modules and functions to execute. +/// * `num_threads` - The number of threads to use for parallel processing. +/// +/// # Examples +/// +/// ``` +/// use pyo3::types::PyModule; +/// use pyo3::types::PyResult; +/// use pyo3::prelude::*; +/// +/// struct PythonModule<'a> { +/// name: &'a str, +/// function: &'a str, +/// args: Vec<&'a str>, +/// } +/// +/// #[pymodule] +/// fn multithreading_processor(modules: Vec, num_threads: usize) -> Result<(), PythonError> { +/// // Function implementation +/// Ok(()) +/// } +/// ``` +/// +/// # Errors +/// +/// Returns a `PythonError` if an import error or a function call error occurs. +/// +/// # Panics +/// +/// This function does not panic. +/// +/// # Safety +/// +/// This function is safe to call, but it assumes that the necessary dependencies (`pyo3`, `rayon`, `log`) are already imported and initialized. +// Initialize Python interpreter #[pyfunction] fn process_python_modules(modules: Vec, num_threads: usize) -> Result<(), PythonError> { - /// The function returns `Ok(())` if all modules are processed successfully. - /// Note: This code assumes that the necessary dependencies (`pyo3`, `rayon`, `log`) are already imported and initialized. - /// - /// # Arguments - /// - /// * `modules` - A vector of `PythonModule` structs representing the Python modules and functions to execute. - /// * `num_threads` - The number of threads to use for parallel processing. - /// - /// # Examples - /// - /// ``` - /// use pyo3::types::PyModule; - /// use pyo3::types::PyResult; - /// use pyo3::prelude::*; - /// - /// struct PythonModule<'a> { - /// name: &'a str, - /// function: &'a str, - /// args: Vec<&'a str>, - /// } - /// - /// #[pymodule] - /// fn multithreading_processor(modules: Vec, num_threads: usize) -> Result<(), PythonError> { - /// // Function implementation - /// Ok(()) - /// } - /// ``` - /// - /// # Errors - /// - /// Returns a `PythonError` if an import error or a function call error occurs. - /// - /// # Panics - /// - /// This function does not panic. - /// - /// # Safety - /// - /// This function is safe to call, but it assumes that the necessary dependencies (`pyo3`, `rayon`, `log`) are already imported and initialized. - // Initialize Python interpreter + let gil = Python::acquire_gil(); let py = gil.python(); diff --git a/tests/agents/test_multion.py b/tests/agents/test_multion.py new file mode 100644 index 00000000..8da68e23 --- /dev/null +++ b/tests/agents/test_multion.py @@ -0,0 +1,57 @@ +import pytest +from unittest.mock import patch, MagicMock +from swarms.agents.multion_agent import MultiOnAgent + + +@patch("swarms.agents.multion_agent.multion") +def test_multion_agent_run(mock_multion): + mock_response = MagicMock() + mock_response.result = "result" + mock_response.status = "status" + mock_response.lastUrl = "lastUrl" + mock_multion.browse.return_value = mock_response + + agent = MultiOnAgent( + multion_api_key="test_key", + max_steps=5, + starting_url="https://www.example.com", + ) + result, status, last_url = agent.run("task") + + assert result == "result" + assert status == "status" + assert last_url == "lastUrl" + mock_multion.browse.assert_called_once_with( + { + "cmd": "task", + "url": "https://www.example.com", + "maxSteps": 5, + } + ) + + +# Additional tests for different tasks +@pytest.mark.parametrize( + "task", ["task1", "task2", "task3", "task4", "task5"] +) +@patch("swarms.agents.multion_agent.multion") +def test_multion_agent_run_different_tasks(mock_multion, task): + mock_response = MagicMock() + mock_response.result = "result" + mock_response.status = "status" + mock_response.lastUrl = "lastUrl" + mock_multion.browse.return_value = mock_response + + agent = MultiOnAgent( + multion_api_key="test_key", + max_steps=5, + starting_url="https://www.example.com", + ) + result, status, last_url = agent.run(task) + + assert result == "result" + assert status == "status" + assert last_url == "lastUrl" + mock_multion.browse.assert_called_once_with( + {"cmd": task, "url": "https://www.example.com", "maxSteps": 5} + )