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
|
||||
|
||||
load_dotenv()
|
||||
|
||||
api_key = os.environ["GEMINI_API_KEY"]
|
||||
|
||||
# Initialize the model
|
||||
model = Gemini(gemini_api_key=api_key)
|
||||
model = Gemini(
|
||||
gemini_api_key="A",
|
||||
)
|
||||
|
||||
# Establish the prompt and image
|
||||
task = "What is your name"
|
||||
img = "images/github-banner-swarms.png"
|
||||
|
||||
# Run the model
|
||||
out = model.run("What is your name?", img=img)
|
||||
out = model.run("What is your name?", img)
|
||||
print(out)
|
||||
|
@ -0,0 +1 @@
|
||||
27dcfa74d334bc871f3234de431e71c6eeba5dd6
|
@ -0,0 +1 @@
|
||||
../../blobs/2d74da6615135c58cf3cf9ad4cb11e7c613ff9e55fe658a47ab83b6c8d1174a9
|
@ -1,78 +1,132 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
List,
|
||||
Union,
|
||||
)
|
||||
|
||||
from dataclass import dataclass, field
|
||||
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
|
||||
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:
|
||||
description (str): The description of the task.
|
||||
agent (Union[Callable, Agent]): The model or agent to execute the task.
|
||||
args (List[Any]): Additional arguments to pass to the task execution.
|
||||
kwargs (Dict[str, Any]): Additional keyword arguments to pass to the task execution.
|
||||
result (Any): The result of the task execution.
|
||||
history (List[Any]): The history of the task execution.
|
||||
id (str): The name of the task.
|
||||
description (Optional[str]): A description of the task.
|
||||
task (str): The name of the task.
|
||||
result (Any): The result of the task.
|
||||
agents (Sequence[Agent]): A list of agents that can execute the task.
|
||||
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:
|
||||
execute: Execute the task.
|
||||
|
||||
execute: Executes the task by passing the results of the parent tasks to the agents.
|
||||
|
||||
Examples:
|
||||
>>> from swarms.structs import Task, Agent
|
||||
>>> from swarms.models import OpenAIChat
|
||||
>>> agent = Agent(llm=OpenAIChat(openai_api_key=""), max_loops=1, dashboard=False)
|
||||
>>> task = Task(description="What's the weather in miami", agent=agent)
|
||||
>>> task.execute()
|
||||
>>> task.result
|
||||
import os
|
||||
from swarms.models import OpenAIChat
|
||||
from swarms.structs import Agent
|
||||
from swarms.structs.sequential_workflow import SequentialWorkflow
|
||||
from dotenv import load_dotenv
|
||||
|
||||
"""
|
||||
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)
|
||||
|
||||
description: str
|
||||
agent: Union[Callable, Agent]
|
||||
args: List[Any] = field(default_factory=list)
|
||||
kwargs: Dict[str, Any] = field(default_factory=dict)
|
||||
result: Any = None
|
||||
history: List[Any] = field(default_factory=list)
|
||||
# logger = logging.getLogger(__name__)
|
||||
# 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}")
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
Execute the task.
|
||||
|
||||
Raises:
|
||||
ValueError: If a Agent instance is used as a task and the 'task' argument is not provided.
|
||||
def __init__(
|
||||
self,
|
||||
id: str,
|
||||
description: Optional[str],
|
||||
task: str,
|
||||
result: Any,
|
||||
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, parent_results: Dict[str, Any]):
|
||||
"""Executes the task by passing the results of the parent tasks to the agents.
|
||||
|
||||
Args:
|
||||
parent_results (Dict[str, Any]): A dictionary of task names and their results.
|
||||
|
||||
Examples:
|
||||
"""
|
||||
if isinstance(self.agent, Agent):
|
||||
# Add a prompt to notify the Agent of the sequential workflow
|
||||
args = [parent_results[dep] for dep in self.dependencies]
|
||||
for agent in self.agents:
|
||||
if isinstance(agent, Agent):
|
||||
if "prompt" in self.kwargs:
|
||||
self.kwargs["prompt"] += (
|
||||
f"\n\nPrevious output: {self.result}"
|
||||
if self.result
|
||||
f"\n\nPrevious output: {self.results[-1]}"
|
||||
if self.results
|
||||
else ""
|
||||
)
|
||||
else:
|
||||
self.kwargs["prompt"] = (
|
||||
f"Main task: {self.description}"
|
||||
+ (
|
||||
f"\n\nPrevious output: {self.result}"
|
||||
if self.result
|
||||
f"\n\nPrevious output: {self.results[-1]}"
|
||||
if self.results
|
||||
else ""
|
||||
)
|
||||
)
|
||||
self.result = self.agent.run(*self.args, **self.kwargs)
|
||||
result = agent.run(
|
||||
self.description, *args, **self.kwargs
|
||||
)
|
||||
else:
|
||||
self.result = self.agent(*self.args, **self.kwargs)
|
||||
|
||||
self.history.append(self.result)
|
||||
result = agent(self.description, *args, **self.kwargs)
|
||||
self.results.append(result)
|
||||
args = [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