[FEAT][MatrixSwarm]

pull/761/head
Kye Gomez 3 months ago
parent e06652ed8b
commit 37894599c2

@ -188,6 +188,7 @@ nav:
- TaskQueueSwarm: "swarms/structs/taskqueue_swarm.md"
- SwarmRearrange: "swarms/structs/swarm_rearrange.md"
- MultiAgentRouter: "swarms/structs/multi_agent_router.md"
- MatrixSwarm: "swarms/structs/matrix_swarm.md"
- Various Execution Methods: "swarms/structs/various_execution_methods.md"
- Workflows:
- ConcurrentWorkflow: "swarms/structs/concurrentworkflow.md"

@ -0,0 +1,247 @@
# MatrixSwarm
The `MatrixSwarm` class provides a framework for managing and operating on matrices of AI agents, enabling matrix-like operations similar to linear algebra. This allows for complex agent interactions and parallel processing capabilities.
## Overview
`MatrixSwarm` treats AI agents as elements in a matrix, allowing for operations like addition, multiplication, and transposition. This approach enables sophisticated agent orchestration and parallel processing patterns.
## Installation
```bash
pip3 install -U swarms
```
## Basic Usage
```python
from swarms import Agent
from swarms.matrix import MatrixSwarm
# Create a 2x2 matrix of agents
agents = [
[Agent(agent_name="Agent-0-0"), Agent(agent_name="Agent-0-1")],
[Agent(agent_name="Agent-1-0"), Agent(agent_name="Agent-1-1")]
]
# Initialize the matrix
matrix = MatrixSwarm(agents)
```
## Class Constructor
```python
def __init__(self, agents: List[List[Agent]])
```
### Parameters
- `agents` (`List[List[Agent]]`): A 2D list of Agent instances representing the matrix.
### Raises
- `ValueError`: If the input is not a valid 2D list of Agent instances.
## Methods
### transpose()
Transposes the matrix of agents by swapping rows and columns.
```python
def transpose(self) -> MatrixSwarm
```
#### Returns
- `MatrixSwarm`: A new MatrixSwarm instance with transposed dimensions.
---
### add(other)
Performs element-wise addition of two agent matrices.
```python
def add(self, other: MatrixSwarm) -> MatrixSwarm
```
#### Parameters
- `other` (`MatrixSwarm`): Another MatrixSwarm instance to add.
#### Returns
- `MatrixSwarm`: A new MatrixSwarm resulting from the addition.
#### Raises
- `ValueError`: If matrix dimensions are incompatible.
---
### scalar_multiply(scalar)
Scales the matrix by duplicating agents along rows.
```python
def scalar_multiply(self, scalar: int) -> MatrixSwarm
```
#### Parameters
- `scalar` (`int`): The multiplication factor.
#### Returns
- `MatrixSwarm`: A new MatrixSwarm with scaled dimensions.
---
### multiply(other, inputs)
Performs matrix multiplication (dot product) between two agent matrices.
```python
def multiply(self, other: MatrixSwarm, inputs: List[str]) -> List[List[AgentOutput]]
```
#### Parameters
- `other` (`MatrixSwarm`): The second MatrixSwarm for multiplication.
- `inputs` (`List[str]`): Input queries for the agents.
#### Returns
- `List[List[AgentOutput]]`: Matrix of operation results.
#### Raises
- `ValueError`: If matrix dimensions are incompatible for multiplication.
---
### subtract(other)
Performs element-wise subtraction of two agent matrices.
```python
def subtract(self, other: MatrixSwarm) -> MatrixSwarm
```
#### Parameters
- `other` (`MatrixSwarm`): Another MatrixSwarm to subtract.
#### Returns
- `MatrixSwarm`: A new MatrixSwarm resulting from the subtraction.
---
### identity(size)
Creates an identity matrix of agents.
```python
def identity(self, size: int) -> MatrixSwarm
```
#### Parameters
- `size` (`int`): Size of the identity matrix (NxN).
#### Returns
- `MatrixSwarm`: An identity MatrixSwarm.
---
### determinant()
Computes the determinant of a square agent matrix.
```python
def determinant(self) -> Any
```
#### Returns
- `Any`: The determinant result.
#### Raises
- `ValueError`: If the matrix is not square.
---
### save_to_file(path)
Saves the matrix structure and metadata to a JSON file.
```python
def save_to_file(self, path: str) -> None
```
#### Parameters
- `path` (`str`): File path for saving the matrix data.
## Extended Example
Here's a comprehensive example demonstrating various MatrixSwarm operations:
```python
from swarms import Agent
from swarms.matrix import MatrixSwarm
# Create agents with specific configurations
agents = [
[
Agent(
agent_name=f"Agent-{i}-{j}",
system_prompt="Your system prompt here",
model_name="gpt-4",
max_loops=1,
verbose=True
) for j in range(2)
] for i in range(2)
]
# Initialize matrix
matrix = MatrixSwarm(agents)
# Example operations
transposed = matrix.transpose()
scaled = matrix.scalar_multiply(2)
# Run operations with inputs
inputs = ["Query 1", "Query 2"]
results = matrix.multiply(transposed, inputs)
# Save results
matrix.save_to_file("matrix_results.json")
```
## Output Schema
The `AgentOutput` class defines the structure for operation results:
```python
class AgentOutput(BaseModel):
agent_name: str
input_query: str
output_result: Any
metadata: dict
```
## Best Practices
1. **Initialization**
- Ensure all agents in the matrix are properly configured before initialization
- Validate matrix dimensions for your use case
2. **Operation Performance**
- Consider computational costs for large matrices
- Use appropriate batch sizes for inputs
3. **Error Handling**
- Implement proper error handling for agent operations
- Validate inputs before matrix operations
4. **Resource Management**
- Monitor agent resource usage in large matrices
- Implement proper cleanup procedures
## Limitations
- Matrix operations are constrained by the underlying agent capabilities
- Performance may vary based on agent configuration and complexity
- Resource usage scales with matrix dimensions
## See Also
- [Swarms Documentation](https://github.com/kyegomez/swarms)
- [Agent Class Reference](https://github.com/kyegomez/swarms/tree/main/swarms)

@ -33,7 +33,7 @@ Main class for routing tasks to different swarm types.
| `flow` | str | The flow of the swarm. |
| `return_json` | bool | Flag to enable/disable returning the result in JSON format. |
| `auto_generate_prompts` | bool | Flag to enable/disable auto generation of prompts. |
| `swarm` | Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow] | Instantiated swarm object. |
| `swarm` | Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow, GroupChat, MultiAgentRouter] | Instantiated swarm object. |
| `logs` | List[SwarmLog] | List of log entries captured during operations. |
#### Methods:
@ -271,6 +271,39 @@ result = concurrent_router.run("Conduct a comprehensive market analysis for Prod
```
### GroupChat
Use Case: Simulating a group chat with multiple agents.
```python
group_chat_router = SwarmRouter(
name="GroupChat",
description="Simulate a group chat with multiple agents",
max_loops=1,
agents=[financial_analyst, market_researcher, competitor_analyst],
swarm_type="GroupChat"
)
result = group_chat_router.run("Conduct a comprehensive market analysis for Product X")
```
### MultiAgentRouter
Use Case: Simulating a group chat with multiple agents.
```python
multi_agent_router = SwarmRouter(
name="MultiAgentRouter",
description="Simulate a group chat with multiple agents",
max_loops=1,
agents=[financial_analyst, market_researcher, competitor_analyst],
swarm_type="MultiAgentRouter"
)
result = multi_agent_router.run("Conduct a comprehensive market analysis for Product X")
```
### Auto Select (Experimental)
Autonomously selects the right swarm by conducting vector search on your input task or name or description or all 3.

@ -161,7 +161,7 @@ print(result)
We're excited to see how you leverage Swarms-Memory in your projects! Join our community on Discord to share your experiences, ask questions, and stay updated on the latest developments.
- **🐦 Twitter**: [Follow us on Twitter](https://twitter.com/swarms_platform)
- **📢 Discord**: [Join the Agora Discord](https://discord.gg/agora)
- **📢 Discord**: [Join the Agora Discord](https://discord.gg/jM3Z6M9uMq)
- **Swarms Platform**: [Visit our website](https://swarms.ai)
- **📙 Documentation**: [Read the Docs](https://docs.swarms.ai)

@ -1,216 +0,0 @@
from swarms.structs.matrix_swarm import MatrixSwarm, AgentOutput
from swarms import Agent
def create_test_matrix(rows: int, cols: int) -> MatrixSwarm:
"""Helper function to create a test agent matrix"""
agents = [
[
Agent(
agent_name=f"TestAgent-{i}-{j}",
system_prompt="Test prompt",
)
for j in range(cols)
]
for i in range(rows)
]
return MatrixSwarm(agents)
def test_init():
"""Test MatrixSwarm initialization"""
# Test valid initialization
matrix = create_test_matrix(2, 2)
assert isinstance(matrix, MatrixSwarm)
assert len(matrix.agents) == 2
assert len(matrix.agents[0]) == 2
# Test invalid initialization
try:
MatrixSwarm([[1, 2], [3, 4]]) # Non-agent elements
assert False, "Should raise ValueError"
except ValueError:
pass
try:
MatrixSwarm([]) # Empty matrix
assert False, "Should raise ValueError"
except ValueError:
pass
def test_transpose():
"""Test matrix transpose operation"""
matrix = create_test_matrix(2, 3)
transposed = matrix.transpose()
assert len(transposed.agents) == 3 # Original cols become rows
assert len(transposed.agents[0]) == 2 # Original rows become cols
# Verify agent positions
for i in range(2):
for j in range(3):
assert (
matrix.agents[i][j].agent_name
== transposed.agents[j][i].agent_name
)
def test_add():
"""Test matrix addition"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.add(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
# Test incompatible dimensions
matrix3 = create_test_matrix(2, 3)
try:
matrix1.add(matrix3)
assert False, "Should raise ValueError"
except ValueError:
pass
def test_scalar_multiply():
"""Test scalar multiplication"""
matrix = create_test_matrix(2, 2)
scalar = 3
result = matrix.scalar_multiply(scalar)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2 * scalar
# Verify agent duplication
for i in range(len(result.agents)):
for j in range(0, len(result.agents[0]), scalar):
original_agent = matrix.agents[i][j // scalar]
for k in range(scalar):
assert (
result.agents[i][j + k].agent_name
== original_agent.agent_name
)
def test_multiply():
"""Test matrix multiplication"""
matrix1 = create_test_matrix(2, 3)
matrix2 = create_test_matrix(3, 2)
inputs = ["test query 1", "test query 2"]
result = matrix1.multiply(matrix2, inputs)
assert len(result) == 2 # Number of rows in first matrix
assert len(result[0]) == 2 # Number of columns in second matrix
# Verify output structure
for row in result:
for output in row:
assert isinstance(output, AgentOutput)
assert isinstance(output.input_query, str)
assert isinstance(output.metadata, dict)
def test_subtract():
"""Test matrix subtraction"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.subtract(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
def test_identity():
"""Test identity matrix creation"""
matrix = create_test_matrix(3, 3)
identity = matrix.identity(3)
assert len(identity.agents) == 3
assert len(identity.agents[0]) == 3
# Verify diagonal elements are from original matrix
for i in range(3):
assert (
identity.agents[i][i].agent_name
== matrix.agents[i][i].agent_name
)
# Verify non-diagonal elements are zero agents
for j in range(3):
if i != j:
assert identity.agents[i][j].agent_name.startswith(
"Zero-Agent"
)
def test_determinant():
"""Test determinant calculation"""
# Test 1x1 matrix
matrix1 = create_test_matrix(1, 1)
det1 = matrix1.determinant()
assert det1 is not None
# Test 2x2 matrix
matrix2 = create_test_matrix(2, 2)
det2 = matrix2.determinant()
assert det2 is not None
# Test non-square matrix
matrix3 = create_test_matrix(2, 3)
try:
matrix3.determinant()
assert False, "Should raise ValueError"
except ValueError:
pass
def test_save_to_file(tmp_path):
"""Test saving matrix to file"""
import os
matrix = create_test_matrix(2, 2)
file_path = os.path.join(tmp_path, "test_matrix.json")
matrix.save_to_file(file_path)
assert os.path.exists(file_path)
# Verify file contents
import json
with open(file_path, "r") as f:
data = json.load(f)
assert "agents" in data
assert "outputs" in data
assert len(data["agents"]) == 2
assert len(data["agents"][0]) == 2
def run_all_tests():
"""Run all test functions"""
test_functions = [
test_init,
test_transpose,
test_add,
test_scalar_multiply,
test_multiply,
test_subtract,
test_identity,
test_determinant,
]
for test_func in test_functions:
try:
test_func()
print(f"{test_func.__name__} passed")
except AssertionError as e:
print(f"{test_func.__name__} failed: {str(e)}")
except Exception as e:
print(
f"{test_func.__name__} failed with exception: {str(e)}"
)
if __name__ == "__main__":
run_all_tests()

@ -0,0 +1,217 @@
from swarms.structs.matrix_swarm import MatrixSwarm, AgentOutput
from swarms import Agent
def create_test_matrix(rows: int, cols: int) -> MatrixSwarm:
"""Helper function to create a test agent matrix"""
agents = [
[
Agent(
agent_name=f"TestAgent-{i}-{j}",
model_name="gpt-4o",
system_prompt="Test prompt",
)
for j in range(cols)
]
for i in range(rows)
]
return MatrixSwarm(agents)
def test_init():
"""Test MatrixSwarm initialization"""
# Test valid initialization
matrix = create_test_matrix(2, 2)
assert isinstance(matrix, MatrixSwarm)
assert len(matrix.agents) == 2
assert len(matrix.agents[0]) == 2
# Test invalid initialization
try:
MatrixSwarm([[1, 2], [3, 4]]) # Non-agent elements
assert False, "Should raise ValueError"
except ValueError:
pass
try:
MatrixSwarm([]) # Empty matrix
assert False, "Should raise ValueError"
except ValueError:
pass
def test_transpose():
"""Test matrix transpose operation"""
matrix = create_test_matrix(2, 3)
transposed = matrix.transpose()
assert len(transposed.agents) == 3 # Original cols become rows
assert len(transposed.agents[0]) == 2 # Original rows become cols
# Verify agent positions
for i in range(2):
for j in range(3):
assert (
matrix.agents[i][j].agent_name
== transposed.agents[j][i].agent_name
)
def test_add():
"""Test matrix addition"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.add(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
# Test incompatible dimensions
matrix3 = create_test_matrix(2, 3)
try:
matrix1.add(matrix3)
assert False, "Should raise ValueError"
except ValueError:
pass
def test_scalar_multiply():
"""Test scalar multiplication"""
matrix = create_test_matrix(2, 2)
scalar = 3
result = matrix.scalar_multiply(scalar)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2 * scalar
# Verify agent duplication
for i in range(len(result.agents)):
for j in range(0, len(result.agents[0]), scalar):
original_agent = matrix.agents[i][j // scalar]
for k in range(scalar):
assert (
result.agents[i][j + k].agent_name
== original_agent.agent_name
)
def test_multiply():
"""Test matrix multiplication"""
matrix1 = create_test_matrix(2, 3)
matrix2 = create_test_matrix(3, 2)
inputs = ["test query 1", "test query 2"]
result = matrix1.multiply(matrix2, inputs)
assert len(result) == 2 # Number of rows in first matrix
assert len(result[0]) == 2 # Number of columns in second matrix
# Verify output structure
for row in result:
for output in row:
assert isinstance(output, AgentOutput)
assert isinstance(output.input_query, str)
assert isinstance(output.metadata, dict)
def test_subtract():
"""Test matrix subtraction"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.subtract(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
def test_identity():
"""Test identity matrix creation"""
matrix = create_test_matrix(3, 3)
identity = matrix.identity(3)
assert len(identity.agents) == 3
assert len(identity.agents[0]) == 3
# Verify diagonal elements are from original matrix
for i in range(3):
assert (
identity.agents[i][i].agent_name
== matrix.agents[i][i].agent_name
)
# Verify non-diagonal elements are zero agents
for j in range(3):
if i != j:
assert identity.agents[i][j].agent_name.startswith(
"Zero-Agent"
)
def test_determinant():
"""Test determinant calculation"""
# Test 1x1 matrix
matrix1 = create_test_matrix(1, 1)
det1 = matrix1.determinant()
assert det1 is not None
# Test 2x2 matrix
matrix2 = create_test_matrix(2, 2)
det2 = matrix2.determinant()
assert det2 is not None
# Test non-square matrix
matrix3 = create_test_matrix(2, 3)
try:
matrix3.determinant()
assert False, "Should raise ValueError"
except ValueError:
pass
def test_save_to_file(tmp_path):
"""Test saving matrix to file"""
import os
matrix = create_test_matrix(2, 2)
file_path = os.path.join(tmp_path, "test_matrix.json")
matrix.save_to_file(file_path)
assert os.path.exists(file_path)
# Verify file contents
import json
with open(file_path, "r") as f:
data = json.load(f)
assert "agents" in data
assert "outputs" in data
assert len(data["agents"]) == 2
assert len(data["agents"][0]) == 2
def run_all_tests():
"""Run all test functions"""
test_functions = [
test_init,
test_transpose,
test_add,
test_scalar_multiply,
test_multiply,
test_subtract,
test_identity,
test_determinant,
]
for test_func in test_functions:
try:
test_func()
print(f"{test_func.__name__} passed")
except AssertionError as e:
print(f"{test_func.__name__} failed: {str(e)}")
except Exception as e:
print(
f"{test_func.__name__} failed with exception: {str(e)}"
)
if __name__ == "__main__":
run_all_tests()
Loading…
Cancel
Save