master
parent
1ab3eeea55
commit
e3ef675fc1
@ -0,0 +1,73 @@
|
||||
name: Docker Build and Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
# Publish semver tags as releases
|
||||
tags: [ 'v*.*.*' ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
env:
|
||||
# Use docker.io for Docker Hub if empty
|
||||
REGISTRY: docker.io
|
||||
# github.repository as <account>/<repo>
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
# This is used to complete the identity challenge
|
||||
# with sigstore/fulcio when running outside of PRs.
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Setup QEMU for multi-platform builds
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
# Setup Docker BuildX
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# Login to Docker Hub
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=sha
|
||||
|
||||
# Build and push Docker image
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
@ -0,0 +1,65 @@
|
||||
from swarms import Agent
|
||||
from swarms.structs.concurrent_workflow import ConcurrentWorkflow
|
||||
|
||||
# Initialize market research agent
|
||||
market_researcher = Agent(
|
||||
agent_name="Market-Researcher",
|
||||
system_prompt="""You are a market research specialist. Your tasks include:
|
||||
1. Analyzing market trends and patterns
|
||||
2. Identifying market opportunities and threats
|
||||
3. Evaluating competitor strategies
|
||||
4. Assessing customer needs and preferences
|
||||
5. Providing actionable market insights""",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
temperature=0.7,
|
||||
# streaming_on=True,
|
||||
)
|
||||
|
||||
# Initialize financial analyst agent
|
||||
financial_analyst = Agent(
|
||||
agent_name="Financial-Analyst",
|
||||
system_prompt="""You are a financial analysis expert. Your responsibilities include:
|
||||
1. Analyzing financial statements
|
||||
2. Evaluating investment opportunities
|
||||
3. Assessing risk factors
|
||||
4. Providing financial forecasts
|
||||
5. Recommending financial strategies""",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
# streaming_on=True,
|
||||
temperature=0.7,
|
||||
)
|
||||
|
||||
# Initialize technical analyst agent
|
||||
technical_analyst = Agent(
|
||||
agent_name="Technical-Analyst",
|
||||
system_prompt="""You are a technical analysis specialist. Your focus areas include:
|
||||
1. Analyzing price patterns and trends
|
||||
2. Evaluating technical indicators
|
||||
3. Identifying support and resistance levels
|
||||
4. Assessing market momentum
|
||||
5. Providing trading recommendations""",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
temperature=0.7,
|
||||
# streaming_on=True,
|
||||
)
|
||||
|
||||
# Create list of agents
|
||||
agents = [market_researcher, financial_analyst, technical_analyst]
|
||||
|
||||
|
||||
router = ConcurrentWorkflow(
|
||||
name="market-analysis-router",
|
||||
agents=agents,
|
||||
max_loops=1,
|
||||
# output_type="all",
|
||||
show_dashboard=True,
|
||||
)
|
||||
|
||||
result = router.run(
|
||||
"Analyze Tesla (TSLA) stock from market, financial, and technical perspectives"
|
||||
)
|
||||
|
||||
print(result)
|
@ -0,0 +1,55 @@
|
||||
from swarms import Agent
|
||||
from swarms.structs.ma_utils import create_agent_map
|
||||
|
||||
# Initialize market research agent
|
||||
market_researcher = Agent(
|
||||
agent_name="Market-Researcher",
|
||||
system_prompt="""You are a market research specialist. Your tasks include:
|
||||
1. Analyzing market trends and patterns
|
||||
2. Identifying market opportunities and threats
|
||||
3. Evaluating competitor strategies
|
||||
4. Assessing customer needs and preferences
|
||||
5. Providing actionable market insights""",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
temperature=0.7,
|
||||
# streaming_on=True,
|
||||
)
|
||||
|
||||
# Initialize financial analyst agent
|
||||
financial_analyst = Agent(
|
||||
agent_name="Financial-Analyst",
|
||||
system_prompt="""You are a financial analysis expert. Your responsibilities include:
|
||||
1. Analyzing financial statements
|
||||
2. Evaluating investment opportunities
|
||||
3. Assessing risk factors
|
||||
4. Providing financial forecasts
|
||||
5. Recommending financial strategies""",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
# streaming_on=True,
|
||||
temperature=0.7,
|
||||
)
|
||||
|
||||
# Initialize technical analyst agent
|
||||
technical_analyst = Agent(
|
||||
agent_name="Technical-Analyst",
|
||||
system_prompt="""You are a technical analysis specialist. Your focus areas include:
|
||||
1. Analyzing price patterns and trends
|
||||
2. Evaluating technical indicators
|
||||
3. Identifying support and resistance levels
|
||||
4. Assessing market momentum
|
||||
5. Providing trading recommendations""",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
temperature=0.7,
|
||||
# streaming_on=True,
|
||||
)
|
||||
|
||||
# Create list of agents
|
||||
agents = [market_researcher, financial_analyst, technical_analyst]
|
||||
|
||||
out = create_agent_map(agents)
|
||||
print(out)
|
||||
|
||||
print(out.keys())
|
@ -1,57 +1,130 @@
|
||||
from concurrent.futures import Future
|
||||
from unittest.mock import Mock, create_autospec, patch
|
||||
|
||||
from swarms.structs import Agent, ConcurrentWorkflow, Task
|
||||
|
||||
|
||||
def test_add():
|
||||
workflow = ConcurrentWorkflow(max_workers=2)
|
||||
task = Mock(spec=Task)
|
||||
workflow.add(task)
|
||||
assert task in workflow.tasks
|
||||
|
||||
|
||||
def test_run():
|
||||
workflow = ConcurrentWorkflow(max_workers=2)
|
||||
task1 = create_autospec(Task)
|
||||
task2 = create_autospec(Task)
|
||||
workflow.add(task1)
|
||||
workflow.add(task2)
|
||||
|
||||
with patch(
|
||||
"concurrent.futures.ThreadPoolExecutor"
|
||||
) as mock_executor:
|
||||
future1 = Future()
|
||||
future1.set_result(None)
|
||||
future2 = Future()
|
||||
future2.set_result(None)
|
||||
|
||||
mock_executor.return_value.__enter__.return_value.submit.side_effect = [
|
||||
future1,
|
||||
future2,
|
||||
]
|
||||
mock_executor.return_value.__enter__.return_value.as_completed.return_value = [
|
||||
future1,
|
||||
future2,
|
||||
]
|
||||
|
||||
workflow.run()
|
||||
|
||||
task1.execute.assert_called_once()
|
||||
task2.execute.assert_called_once()
|
||||
|
||||
|
||||
def test_execute_task():
|
||||
workflow = ConcurrentWorkflow(max_workers=2)
|
||||
task = create_autospec(Task)
|
||||
workflow._execute_task(task)
|
||||
task.execute.assert_called_once()
|
||||
|
||||
|
||||
def test_agent_execution():
|
||||
workflow = ConcurrentWorkflow(max_workers=2)
|
||||
agent = create_autospec(Agent)
|
||||
task = Task(agent)
|
||||
workflow.add(task)
|
||||
workflow._execute_task(task)
|
||||
agent.execute.assert_called_once()
|
||||
from swarms import Agent
|
||||
from swarms.structs.concurrent_workflow import ConcurrentWorkflow
|
||||
|
||||
|
||||
def test_basic_workflow():
|
||||
"""Test basic workflow initialization and execution"""
|
||||
# Create test agents
|
||||
agent1 = Agent(
|
||||
agent_name="Test-Agent-1",
|
||||
system_prompt="You are a test agent 1",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
agent_name="Test-Agent-2",
|
||||
system_prompt="You are a test agent 2",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
)
|
||||
|
||||
# Create workflow
|
||||
workflow = ConcurrentWorkflow(
|
||||
name="test-workflow", agents=[agent1, agent2], max_loops=1
|
||||
)
|
||||
|
||||
# Run workflow
|
||||
result = workflow.run("Test task")
|
||||
|
||||
# Verify results
|
||||
assert len(result) == 2
|
||||
assert all(isinstance(r, dict) for r in result)
|
||||
assert all("agent" in r and "output" in r for r in result)
|
||||
|
||||
|
||||
def test_dashboard_workflow():
|
||||
"""Test workflow with dashboard enabled"""
|
||||
agent = Agent(
|
||||
agent_name="Dashboard-Test-Agent",
|
||||
system_prompt="You are a test agent",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
)
|
||||
|
||||
workflow = ConcurrentWorkflow(
|
||||
name="dashboard-test",
|
||||
agents=[agent],
|
||||
max_loops=1,
|
||||
show_dashboard=True,
|
||||
)
|
||||
|
||||
result = workflow.run("Test task")
|
||||
|
||||
assert len(result) == 1
|
||||
assert isinstance(result[0], dict)
|
||||
assert "agent" in result[0]
|
||||
assert "output" in result[0]
|
||||
|
||||
|
||||
def test_multiple_agents():
|
||||
"""Test workflow with multiple agents"""
|
||||
agents = [
|
||||
Agent(
|
||||
agent_name=f"Agent-{i}",
|
||||
system_prompt=f"You are test agent {i}",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=1,
|
||||
)
|
||||
for i in range(3)
|
||||
]
|
||||
|
||||
workflow = ConcurrentWorkflow(
|
||||
name="multi-agent-test", agents=agents, max_loops=1
|
||||
)
|
||||
|
||||
result = workflow.run("Multi-agent test task")
|
||||
|
||||
assert len(result) == 3
|
||||
assert all(isinstance(r, dict) for r in result)
|
||||
assert all("agent" in r and "output" in r for r in result)
|
||||
|
||||
|
||||
def test_error_handling():
|
||||
"""Test workflow error handling"""
|
||||
# Create an agent that will raise an exception
|
||||
agent = Agent(
|
||||
agent_name="Error-Agent",
|
||||
system_prompt="You are a test agent that will raise an error",
|
||||
model_name="invalid-model", # This will cause an error
|
||||
max_loops=1,
|
||||
)
|
||||
|
||||
workflow = ConcurrentWorkflow(
|
||||
name="error-test", agents=[agent], max_loops=1
|
||||
)
|
||||
|
||||
try:
|
||||
workflow.run("Test task")
|
||||
assert False, "Expected an error but none was raised"
|
||||
except Exception as e:
|
||||
assert str(e) != "" # Verify we got an error message
|
||||
|
||||
|
||||
def test_max_loops():
|
||||
"""Test workflow respects max_loops setting"""
|
||||
agent = Agent(
|
||||
agent_name="Loop-Test-Agent",
|
||||
system_prompt="You are a test agent",
|
||||
model_name="claude-3-sonnet-20240229",
|
||||
max_loops=2,
|
||||
)
|
||||
|
||||
workflow = ConcurrentWorkflow(
|
||||
name="loop-test",
|
||||
agents=[agent],
|
||||
max_loops=1, # This should override agent's max_loops
|
||||
)
|
||||
|
||||
result = workflow.run("Test task")
|
||||
|
||||
assert len(result) == 1
|
||||
assert isinstance(result[0], dict)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_basic_workflow()
|
||||
test_dashboard_workflow()
|
||||
test_multiple_agents()
|
||||
test_error_handling()
|
||||
test_max_loops()
|
||||
|
Loading…
Reference in new issue