commit
e9b2800815
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
name: Docker Image CI
|
||||||
|
|
||||||
|
on: # yamllint disable-line rule:truthy
|
||||||
|
push:
|
||||||
|
branches: ["master"]
|
||||||
|
pull_request:
|
||||||
|
branches: ["master"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Build Docker image
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build the Docker image
|
||||||
|
run: docker build . --file Dockerfile --tag my-image-name:$(date +%s)
|
@ -0,0 +1,98 @@
|
|||||||
|
name: Docker
|
||||||
|
|
||||||
|
# This workflow uses actions that are not certified by GitHub.
|
||||||
|
# They are provided by a third-party and are governed by
|
||||||
|
# separate terms of service, privacy policy, and support
|
||||||
|
# documentation.
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '31 19 * * *'
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
# Publish semver tags as releases.
|
||||||
|
tags: [ 'v*.*.*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Use docker.io for Docker Hub if empty
|
||||||
|
REGISTRY: ghcr.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
|
||||||
|
|
||||||
|
# Install the cosign tool except on PR
|
||||||
|
# https://github.com/sigstore/cosign-installer
|
||||||
|
- name: Install cosign
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 #v3.2.0
|
||||||
|
with:
|
||||||
|
cosign-release: 'v2.1.1'
|
||||||
|
|
||||||
|
# Set up BuildKit Docker container builder to be able to build
|
||||||
|
# multi-platform images and export cache
|
||||||
|
# https://github.com/docker/setup-buildx-action
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||||
|
|
||||||
|
# Login against a Docker registry except on PR
|
||||||
|
# https://github.com/docker/login-action
|
||||||
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# Extract metadata (tags, labels) for Docker
|
||||||
|
# https://github.com/docker/metadata-action
|
||||||
|
- name: Extract Docker metadata
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@31cebacef4805868f9ce9a0cb03ee36c32df2ac4 # v5.3.0
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
|
# Build and push Docker image with Buildx (don't push on PR)
|
||||||
|
# https://github.com/docker/build-push-action
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
# Sign the resulting Docker image digest except on PRs.
|
||||||
|
# This will only write to the public Rekor transparency log when the Docker
|
||||||
|
# repository is public to avoid leaking data. If you would like to publish
|
||||||
|
# transparency data even for private images, pass --force to cosign below.
|
||||||
|
# https://github.com/sigstore/cosign
|
||||||
|
- name: Sign the published Docker image
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
env:
|
||||||
|
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
|
||||||
|
TAGS: ${{ steps.meta.outputs.tags }}
|
||||||
|
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||||
|
# This step uses the identity token to provision an ephemeral certificate
|
||||||
|
# against the sigstore community Fulcio instance.
|
||||||
|
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
|
@ -0,0 +1,34 @@
|
|||||||
|
name: Python Package using Conda
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
max-parallel: 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python 3.10
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.10'
|
||||||
|
- name: Add conda to system path
|
||||||
|
run: |
|
||||||
|
# $CONDA is an environment variable pointing to the root of the miniconda directory
|
||||||
|
echo $CONDA/bin >> $GITHUB_PATH
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
conda env update --file environment.yml --name base
|
||||||
|
- name: Lint with flake8
|
||||||
|
run: |
|
||||||
|
conda install flake8
|
||||||
|
# stop the build if there are Python syntax errors or undefined names
|
||||||
|
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
|
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||||
|
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||||
|
- name: Test with pytest
|
||||||
|
run: |
|
||||||
|
conda install pytest
|
||||||
|
pytest
|
@ -1,18 +1,14 @@
|
|||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
from swarms.models.gemini import Gemini
|
from swarms.models.gemini import Gemini
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
api_key = os.environ["GEMINI_API_KEY"]
|
|
||||||
|
|
||||||
# Initialize the model
|
# Initialize the model
|
||||||
model = Gemini(gemini_api_key=api_key)
|
model = Gemini(
|
||||||
|
gemini_api_key="A",
|
||||||
|
)
|
||||||
|
|
||||||
# Establish the prompt and image
|
# Establish the prompt and image
|
||||||
task = "What is your name"
|
task = "What is your name"
|
||||||
img = "images/github-banner-swarms.png"
|
img = "images/github-banner-swarms.png"
|
||||||
|
|
||||||
# Run the model
|
# Run the model
|
||||||
out = model.run("What is your name?", img=img)
|
out = model.run("What is your name?", img)
|
||||||
print(out)
|
print(out)
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
27dcfa74d334bc871f3234de431e71c6eeba5dd6
|
@ -0,0 +1 @@
|
|||||||
|
../../blobs/2d74da6615135c58cf3cf9ad4cb11e7c613ff9e55fe658a47ab83b6c8d1174a9
|
@ -1,78 +1,132 @@
|
|||||||
from dataclasses import dataclass, field
|
from dataclass import dataclass, field
|
||||||
from typing import (
|
|
||||||
Any,
|
|
||||||
Callable,
|
|
||||||
Dict,
|
|
||||||
List,
|
|
||||||
Union,
|
|
||||||
)
|
|
||||||
|
|
||||||
from swarms.structs.agent import Agent
|
from swarms.structs.agent import Agent
|
||||||
|
from typing import Optional
|
||||||
|
from typing import List, Dict, Any, Sequence
|
||||||
|
|
||||||
|
|
||||||
# Define a generic Task that can handle different types of callable objects
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Task:
|
class Task:
|
||||||
"""
|
"""
|
||||||
Task class for running a task in a sequential workflow.
|
Task is a unit of work that can be executed by a set of agents.
|
||||||
|
|
||||||
|
A task is defined by a task name and a set of agents that can execute the task.
|
||||||
|
The task can also have a set of dependencies, which are the names of other tasks
|
||||||
|
that must be executed before this task can be executed.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
description (str): The description of the task.
|
id (str): The name of the task.
|
||||||
agent (Union[Callable, Agent]): The model or agent to execute the task.
|
description (Optional[str]): A description of the task.
|
||||||
args (List[Any]): Additional arguments to pass to the task execution.
|
task (str): The name of the task.
|
||||||
kwargs (Dict[str, Any]): Additional keyword arguments to pass to the task execution.
|
result (Any): The result of the task.
|
||||||
result (Any): The result of the task execution.
|
agents (Sequence[Agent]): A list of agents that can execute the task.
|
||||||
history (List[Any]): The history of the task execution.
|
dependencies (List[str], optional): A list of task names that must be executed before this task can be executed. Defaults to [].
|
||||||
|
args (List[Any], optional): A list of arguments to pass to the agents. Defaults to field(default_factory=list).
|
||||||
|
kwargs (List[Any], optional): A list of keyword arguments to pass to the agents. Defaults to field(default_factory=list).
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
execute: Execute the task.
|
execute: Executes the task by passing the results of the parent tasks to the agents.
|
||||||
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
>>> from swarms.structs import Task, Agent
|
import os
|
||||||
>>> from swarms.models import OpenAIChat
|
from swarms.models import OpenAIChat
|
||||||
>>> agent = Agent(llm=OpenAIChat(openai_api_key=""), max_loops=1, dashboard=False)
|
from swarms.structs import Agent
|
||||||
>>> task = Task(description="What's the weather in miami", agent=agent)
|
from swarms.structs.sequential_workflow import SequentialWorkflow
|
||||||
>>> task.execute()
|
from dotenv import load_dotenv
|
||||||
>>> task.result
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Load the environment variables
|
||||||
|
api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize the language agent
|
||||||
|
llm = OpenAIChat(
|
||||||
|
openai_api_key=api_key,
|
||||||
|
temperature=0.5,
|
||||||
|
max_tokens=3000,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize the agent with the language agent
|
||||||
|
agent1 = Agent(llm=llm, max_loops=1)
|
||||||
|
|
||||||
|
# Create another agent for a different task
|
||||||
|
agent2 = Agent(llm=llm, max_loops=1)
|
||||||
|
|
||||||
|
# Create the workflow
|
||||||
|
workflow = SequentialWorkflow(max_loops=1)
|
||||||
|
|
||||||
|
# Add tasks to the workflow
|
||||||
|
workflow.add(
|
||||||
|
agent1, "Generate a 10,000 word blog on health and wellness.",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Suppose the next task takes the output of the first task as input
|
||||||
|
workflow.add(
|
||||||
|
agent2, "Summarize the generated blog",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Run the workflow
|
||||||
|
workflow.run()
|
||||||
|
|
||||||
|
# Output the results
|
||||||
|
for task in workflow.tasks:
|
||||||
|
print(f"Task: {task.description}, Result: {task.result}")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
description: str
|
def __init__(
|
||||||
agent: Union[Callable, Agent]
|
self,
|
||||||
args: List[Any] = field(default_factory=list)
|
id: str,
|
||||||
kwargs: Dict[str, Any] = field(default_factory=dict)
|
description: Optional[str],
|
||||||
result: Any = None
|
task: str,
|
||||||
history: List[Any] = field(default_factory=list)
|
result: Any,
|
||||||
# logger = logging.getLogger(__name__)
|
agents: Sequence[Agent],
|
||||||
|
dependencies: List[str] = [],
|
||||||
|
args: List[Any] = field(default_factory=list),
|
||||||
|
kwargs: List[Any] = field(default_factory=list),
|
||||||
|
):
|
||||||
|
self.id = id
|
||||||
|
self.description = description
|
||||||
|
self.task = task
|
||||||
|
self.result = result
|
||||||
|
self.agents = agents
|
||||||
|
self.dependencies = dependencies
|
||||||
|
self.results = []
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def execute(self):
|
def execute(self, parent_results: Dict[str, Any]):
|
||||||
"""
|
"""Executes the task by passing the results of the parent tasks to the agents.
|
||||||
Execute the task.
|
|
||||||
|
Args:
|
||||||
|
parent_results (Dict[str, Any]): A dictionary of task names and their results.
|
||||||
|
|
||||||
Raises:
|
Examples:
|
||||||
ValueError: If a Agent instance is used as a task and the 'task' argument is not provided.
|
|
||||||
"""
|
"""
|
||||||
if isinstance(self.agent, Agent):
|
args = [parent_results[dep] for dep in self.dependencies]
|
||||||
# Add a prompt to notify the Agent of the sequential workflow
|
for agent in self.agents:
|
||||||
if "prompt" in self.kwargs:
|
if isinstance(agent, Agent):
|
||||||
self.kwargs["prompt"] += (
|
if "prompt" in self.kwargs:
|
||||||
f"\n\nPrevious output: {self.result}"
|
self.kwargs["prompt"] += (
|
||||||
if self.result
|
f"\n\nPrevious output: {self.results[-1]}"
|
||||||
else ""
|
if self.results
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.kwargs["prompt"] = (
|
|
||||||
f"Main task: {self.description}"
|
|
||||||
+ (
|
|
||||||
f"\n\nPrevious output: {self.result}"
|
|
||||||
if self.result
|
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
self.kwargs["prompt"] = (
|
||||||
|
f"Main task: {self.description}"
|
||||||
|
+ (
|
||||||
|
f"\n\nPrevious output: {self.results[-1]}"
|
||||||
|
if self.results
|
||||||
|
else ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
result = agent.run(
|
||||||
|
self.description, *args, **self.kwargs
|
||||||
)
|
)
|
||||||
self.result = self.agent.run(*self.args, **self.kwargs)
|
else:
|
||||||
else:
|
result = agent(self.description, *args, **self.kwargs)
|
||||||
self.result = self.agent(*self.args, **self.kwargs)
|
self.results.append(result)
|
||||||
|
args = [result]
|
||||||
self.history.append(self.result)
|
self.history.append(result)
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
from swarms.telemetry.user_utils import (
|
||||||
|
generate_unique_identifier,
|
||||||
|
generate_user_id,
|
||||||
|
get_machine_id,
|
||||||
|
get_system_info,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Helper functions tests
|
||||||
|
def test_generate_user_id():
|
||||||
|
# Generate user IDs and ensure they are UUID strings
|
||||||
|
user_id = generate_user_id()
|
||||||
|
assert isinstance(user_id, str)
|
||||||
|
assert uuid.UUID(user_id, version=4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_machine_id():
|
||||||
|
# Get machine ID and ensure it's a valid SHA-256 hash
|
||||||
|
machine_id = get_machine_id()
|
||||||
|
assert isinstance(machine_id, str)
|
||||||
|
assert len(machine_id) == 64
|
||||||
|
assert all(char in "0123456789abcdef" for char in machine_id)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_system_info():
|
||||||
|
# Get system information and ensure it's a dictionary with expected keys
|
||||||
|
system_info = get_system_info()
|
||||||
|
assert isinstance(system_info, dict)
|
||||||
|
expected_keys = [
|
||||||
|
"platform",
|
||||||
|
"platform_release",
|
||||||
|
"platform_version",
|
||||||
|
"architecture",
|
||||||
|
"hostname",
|
||||||
|
"ip_address",
|
||||||
|
"mac_address",
|
||||||
|
"processor",
|
||||||
|
"python_version",
|
||||||
|
]
|
||||||
|
assert all(key in system_info for key in expected_keys)
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_unique_identifier():
|
||||||
|
# Generate unique identifiers and ensure they are valid UUID strings
|
||||||
|
unique_id = generate_unique_identifier()
|
||||||
|
assert isinstance(unique_id, str)
|
||||||
|
assert uuid.UUID(
|
||||||
|
unique_id, version=5, namespace=uuid.NAMESPACE_DNS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_user_id_edge_case():
|
||||||
|
# Test generate_user_id with multiple calls
|
||||||
|
user_ids = set()
|
||||||
|
for _ in range(100):
|
||||||
|
user_id = generate_user_id()
|
||||||
|
user_ids.add(user_id)
|
||||||
|
assert len(user_ids) == 100 # Ensure generated IDs are unique
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_machine_id_edge_case():
|
||||||
|
# Test get_machine_id with multiple calls
|
||||||
|
machine_ids = set()
|
||||||
|
for _ in range(100):
|
||||||
|
machine_id = get_machine_id()
|
||||||
|
machine_ids.add(machine_id)
|
||||||
|
assert len(machine_ids) == 100 # Ensure generated IDs are unique
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_system_info_edge_case():
|
||||||
|
# Test get_system_info for consistency
|
||||||
|
system_info1 = get_system_info()
|
||||||
|
system_info2 = get_system_info()
|
||||||
|
assert (
|
||||||
|
system_info1 == system_info2
|
||||||
|
) # Ensure system info remains the same
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_unique_identifier_edge_case():
|
||||||
|
# Test generate_unique_identifier for uniqueness
|
||||||
|
unique_ids = set()
|
||||||
|
for _ in range(100):
|
||||||
|
unique_id = generate_unique_identifier()
|
||||||
|
unique_ids.add(unique_id)
|
||||||
|
assert len(unique_ids) == 100 # Ensure generated IDs are unique
|
Loading…
Reference in new issue