Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.git
.omx
.pytest_cache
.venv
.env
.env.*
!.env.example
__pycache__
*.pyc
*.pyo
*.pyd
*.swp
*.swo
*~
._*
Thumbs.db
.DS_Store
AWSCLIV2.pkg
docker_container
grpc_stubs
stubs
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ env/
# OS files
.DS_Store
Thumbs.db
._*

# Generated stubs
stubs/
Expand All @@ -32,3 +33,10 @@ docker_container/

# Logs
*.log

# Local env / machine artifacts
.env
.env.*
!.env.example
AWSCLIV2.pkg
.python-version
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ cp -r ../examples/* ./
## Deployment Guide

#### Step 1: Configure the Global Controller
Edit `examples/config/global_controller.yaml` to list the agents you want to deploy, their hosts, ports, and resource limits.
Edit `config/global_controller.yaml` in your project directory to list the agents you want to deploy, their `provider`, `replicas`, and resource limits.

#### Step 2: Build the project
```bash
Expand All @@ -89,10 +89,10 @@ Upon running the deploy command, ventis automatically generates a REST API endpo
Users can send requests to this endpoint to trigger the workflow. For this example, workflow to send a request -

```bash
curl -X POST http://localhost:8080/finance_workflow/run \
curl -X POST http://localhost:8080/main \
-H "Content-Type: application/json" \
-d '{
"query": "What is the current stock price of Apple?"
"ticker": "AAPL"
}'
```
The request is asynchronous. To get the result, you use the following URL-
Expand All @@ -105,7 +105,7 @@ curl http://localhost:8080/status/<request_id>
Remove all generated stub and gRPC files:

```bash
make clean
ventis clean
```

### Harnessing the power of Ventis
Expand Down
33 changes: 33 additions & 0 deletions examples/config/global_controller.ec2_smoke.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Cheapest EC2 smoke test:
# - exactly 2 agent instances
# - generic agent image + bind-mounted project code
# - t2.nano for lowest-cost MVP validation

agents:
- name: MarketResearchAgent
replicas: 2
redis_port: 6379
resources:
cpu: 1
memory: 256
entrypoint: agents/market_agent.py
provider: EC2

poll_interval: 5

redis:
host: localhost
port: 6379
db: 0

ec2:
region: us-east-1
ami_id: ami-0123456789abcdef0
instance_type: t2.nano
subnet_id: subnet-0123456789abcdef0
security_group_ids:
- sg-0123456789abcdef0
ssh_user: ubuntu
key_name: ventis-key
agent_image: ventis-agent-base
remote_project_dir: /opt/ventis/project
62 changes: 31 additions & 31 deletions examples/config/global_controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,70 @@

agents:
- name: FinanceAgent
# Replicas can be placed on different hosts with explicit host/port.
# Alternatively, use `replicas: 3` as shorthand to launch 3 instances
# on the same host with sequential ports starting from `port`.
replicas:
- host: localhost
port: 8051
- host: localhost
port: 8052
redis_port: 6379 # Redis port on this node
# user: sagarwal # SSH user for remote hosts (omit for localhost)
# Stateful agents get session affinity: all calls within a single
# request_id are routed to the same instance.
replicas: 2
redis_port: 6379 # Redis port on this node
stateful: true
# Resource limits per instance
resources:
cpu: 1 # Number of CPU cores
memory: 512 # Memory in MB
# Path to the agent entrypoint script
cpu: 1
memory: 512
entrypoint: agents/finance_agent.py
provider: local

- name: MarketResearchAgent
host: localhost
port: 8053
redis_port: 6379
# user: sagarwal
replicas: 1
redis_port: 6379
resources:
cpu: 1
memory: 512
entrypoint: agents/market_agent.py
provider: local

- name: VllmAgent
host: localhost
port: 8054
redis_port: 6379
replicas: 1
redis_port: 6379
resources:
cpu: 2
memory: 2048
entrypoint: agents/vllm_agent.py
provider: local

- name: Workflow
host: localhost
port: 8050 # LC gRPC port (exposed to host)
replicas: 1
type: workflow
api_port: 8080 # Flask REST API port (exposed to host)
redis_port: 6379
replicas: 1
workflow_file: workflows/example_workflow.py
provider: local

# Polling interval in seconds
poll_interval: 5

# Redis connection
redis:
host: localhost
port: 6379
db: 0

# EC2 defaults for `provider: EC2` replicas.
# MVP expects the subnet/security group/network path to already allow
# controller -> public_ip:50051 for agent gRPC and controller -> public_ip:6379
# for the per-instance Redis container. Restrict both inbound rules to the
# global controller host's source IP.
#
# ec2:
# region: us-east-1
# ami_id: ami-0123456789abcdef0
# instance_type: t2.nano
# subnet_id: subnet-0123456789abcdef0
# security_group_ids:
# - sg-0123456789abcdef0
# ssh_user: ubuntu
# key_name: ventis-key
# agent_image: ventis-agent-base
# remote_project_dir: /opt/ventis/project

# Docker image registry (optional).
# If set, `ventis deploy` will push images to this registry locally and
# pull them on remote nodes before starting containers.
# If omitted, images are shipped to remote nodes via `docker save | ssh ... docker load`.
#
# registry:
# url: myregistry.example.com:5000 # Registry host:port
# user: sagarwal # (optional) SSH user used when pulling on remote nodes
# url: myregistry.example.com:5000
# user: sagarwal
3 changes: 3 additions & 0 deletions examples/ec2/agents/example_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class ExampleAgent:
def hello(self, name: str) -> str:
return f"Hello, {name}!"
12 changes: 12 additions & 0 deletions examples/ec2/agents/example_agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
agent:
name: ExampleAgent
methods:
- name: hello
input_schema:
type: object
properties:
name:
type: string
required: [name]
output_schema:
type: string
31 changes: 31 additions & 0 deletions examples/ec2/config/global_controller.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Global controller config for this EC2 example.

agents:
- name: ExampleAgent
replicas: 2
redis_port: 6379
resources:
cpu: 1
memory: 256
entrypoint: agents/example_agent.py
provider: EC2

poll_interval: 5

redis:
host: localhost
port: 6379
db: 0

ec2:
region: us-east-1
ami_id: ami-08f44e8eca9095668
instance_type: t2.nano
subnet_id: subnet-0638ac6d79d488124
security_group_ids:
- sg-08d81e58ac5818c60
ssh_user: ec2-user
ssh_private_key_path: /home/ec2-user/.ssh/saakec2.pem
key_name: saakec2
agent_image: ventis-agent-base
remote_project_dir: /opt/ventis/project
16 changes: 16 additions & 0 deletions examples/ec2/docker/generic-agent.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.12-slim

WORKDIR /workspace

ENV PYTHONUNBUFFERED=1

RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt

COPY . /workspace

CMD ["python", "-m", "ventis.controller.local_controller"]
16 changes: 16 additions & 0 deletions examples/ec2/docker/global-controller.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.12-slim

WORKDIR /workspace

ENV PYTHONUNBUFFERED=1

RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential docker.io openssh-client \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt

COPY . /workspace

CMD ["python", "-m", "ventis.cli", "deploy"]
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
description = "Distributed agent orchestration framework"
requires-python = ">=3.10"
dependencies = [
"boto3",
"grpcio",
"grpcio-tools",
"redis",
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
boto3
grpcio
grpcio-tools
redis
Expand Down
1 change: 1 addition & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This directory contains an automated end-to-end testing suite for Ventis. It is

## 1. Automated Test Runner (`run_tests.sh`)
This script automates the entire testing lifecycle by interacting with the `ventis` CLI:
0. Runs the repo pytest suite.
1. Scaffolds a new temporary project using `ventis new-project`.
2. Compiles the project using `ventis build`.
3. Launches the project using `ventis deploy` in the background.
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions tests/global_controller/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading
Loading