mirror of https://github.com/kortix-ai/suna.git
migrate: switch to uv from poetry
This commit is contained in:
parent
f72440d652
commit
64b4be39fe
|
@ -0,0 +1,133 @@
|
|||
# Version control
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Virtual environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# IDE and editors
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# Test coverage
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Documentation
|
||||
docs/
|
||||
*.md
|
||||
README*
|
||||
|
||||
# CI/CD
|
||||
.github/
|
||||
.gitlab-ci.yml
|
||||
.travis.yml
|
||||
.circleci/
|
||||
|
||||
# Docker
|
||||
Dockerfile*
|
||||
docker-compose*.yml
|
||||
.dockerignore
|
||||
|
||||
# Development tools
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
.pyre/
|
||||
.pytype/
|
||||
cython_debug/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# Environment variables (keep .env files out for security)
|
||||
.env*
|
||||
!.env.example
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
.tmp/
|
||||
.temp/
|
||||
|
||||
# Node.js (if any frontend assets)
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Database
|
||||
*.db
|
||||
*.sqlite3
|
||||
|
||||
# Certificates and keys
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.cert
|
||||
|
||||
# Local development files
|
||||
.local/
|
||||
.cache/
|
|
@ -1,56 +0,0 @@
|
|||
name: Bump Version
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_part:
|
||||
description: 'Part of version to bump (major, minor, patch)'
|
||||
required: true
|
||||
default: 'patch'
|
||||
type: choice
|
||||
options:
|
||||
- major
|
||||
- minor
|
||||
- patch
|
||||
|
||||
# Add these permissions
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
bump-version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install Poetry
|
||||
run: |
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
|
||||
- name: Bump version
|
||||
run: |
|
||||
poetry version ${{ github.event.inputs.version_part }}
|
||||
NEW_VERSION=$(poetry version -s)
|
||||
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: "chore: bump version to ${{ env.NEW_VERSION }}"
|
||||
title: "Bump version to ${{ env.NEW_VERSION }}"
|
||||
body: "Automated version bump to ${{ env.NEW_VERSION }}"
|
||||
branch: "bump-version-${{ env.NEW_VERSION }}"
|
||||
base: "main"
|
|
@ -1,27 +0,0 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install Poetry
|
||||
run: |
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
|
||||
- name: Update lock file and install dependencies
|
||||
run: |
|
||||
poetry lock
|
||||
poetry install
|
|
@ -1,33 +0,0 @@
|
|||
name: Publish to PyPI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
# Allows manual trigger from GitHub Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install Poetry
|
||||
run: |
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
|
||||
- name: Configure Poetry
|
||||
run: |
|
||||
poetry config pypi-token.pypi ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
- name: Build package
|
||||
run: poetry build
|
||||
|
||||
- name: Publish to PyPI
|
||||
run: poetry publish
|
|
@ -1,63 +1,54 @@
|
|||
FROM python:3.11-slim
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1 \
|
||||
ENV_MODE="production" \
|
||||
PYTHONPATH=/app
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV ENV_MODE production
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create non-root user and set up directories
|
||||
RUN useradd -m -u 1000 appuser && \
|
||||
mkdir -p /app/logs && \
|
||||
chown -R appuser:appuser /app
|
||||
build-essential \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python dependencies
|
||||
COPY --chown=appuser:appuser requirements.txt .
|
||||
COPY --chown=appuser:appuser pyproject.toml uv.lock ./
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
||||
RUN uv pip install --system --no-cache-dir -r requirements.txt gunicorn
|
||||
|
||||
# Switch to non-root user
|
||||
USER appuser
|
||||
ENV UV_LINK_MODE=copy
|
||||
ENV UV_PYTHON_PREFERENCE=system
|
||||
# RUN --mount=type=cache,target=/root/.cache/uv uv sync --locked --compile-bytecode --no-editable
|
||||
RUN uv venv --system-site-packages
|
||||
RUN --mount=type=cache,target=/root/.cache/uv uv sync --locked --quiet
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
|
||||
# Copy application code
|
||||
COPY --chown=appuser:appuser . .
|
||||
|
||||
# Expose the port the app runs on
|
||||
EXPOSE 8000
|
||||
COPY . .
|
||||
RUN uv run python --version
|
||||
|
||||
# Calculate optimal worker count based on 16 vCPUs
|
||||
# Using (2*CPU)+1 formula for CPU-bound applications
|
||||
ENV WORKERS=33
|
||||
ENV THREADS=2
|
||||
ENV WORKERS=1
|
||||
ENV THREADS=1
|
||||
ENV WORKER_CONNECTIONS=2000
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
# Gunicorn configuration
|
||||
CMD ["sh", "-c", "gunicorn api:app \
|
||||
--workers $WORKERS \
|
||||
--worker-class uvicorn.workers.UvicornWorker \
|
||||
--bind 0.0.0.0:8000 \
|
||||
--timeout 1800 \
|
||||
--graceful-timeout 600 \
|
||||
--keep-alive 1800 \
|
||||
--max-requests 0 \
|
||||
--max-requests-jitter 0 \
|
||||
--forwarded-allow-ips '*' \
|
||||
--worker-connections $WORKER_CONNECTIONS \
|
||||
--worker-tmp-dir /dev/shm \
|
||||
--preload \
|
||||
--log-level info \
|
||||
--access-logfile - \
|
||||
--error-logfile - \
|
||||
--capture-output \
|
||||
--enable-stdio-inheritance \
|
||||
--threads $THREADS"]
|
||||
CMD ["sh", "-c", "uv run gunicorn api:app \
|
||||
--workers $WORKERS \
|
||||
--worker-class uvicorn.workers.UvicornWorker \
|
||||
--bind 0.0.0.0:8000 \
|
||||
--timeout 1800 \
|
||||
--graceful-timeout 600 \
|
||||
--keep-alive 1800 \
|
||||
--max-requests 0 \
|
||||
--max-requests-jitter 0 \
|
||||
--forwarded-allow-ips '*' \
|
||||
--worker-connections $WORKER_CONNECTIONS \
|
||||
--worker-tmp-dir /dev/shm \
|
||||
--preload \
|
||||
--log-level info \
|
||||
--access-logfile - \
|
||||
--error-logfile - \
|
||||
--capture-output \
|
||||
--enable-stdio-inheritance \
|
||||
--threads $THREADS"]
|
||||
|
|
|
@ -40,11 +40,11 @@ Then you can run your API service locally with the following commands
|
|||
```sh
|
||||
# On one terminal
|
||||
cd backend
|
||||
poetry run python3.11 api.py
|
||||
uv run python api.py
|
||||
|
||||
# On another terminal
|
||||
cd frontend
|
||||
poetry run python3.11 -m dramatiq run_agent_background
|
||||
uv run python -m dramatiq run_agent_background
|
||||
```
|
||||
|
||||
### Environment Configuration
|
||||
|
|
|
@ -10,7 +10,7 @@ services:
|
|||
memory: 32G
|
||||
|
||||
worker:
|
||||
command: python -m dramatiq --processes 40 --threads 8 run_agent_background
|
||||
command: uvx dramatiq --processes 40 --threads 8 run_agent_background
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
|
|
|
@ -42,7 +42,8 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
command: python -m dramatiq --processes 4 --threads 4 run_agent_background
|
||||
command: sleep infinity
|
||||
# command: dramatiq --processes 4 --threads 4 run_agent_background
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
source .venv/bin/activate
|
||||
exec "$@"
|
File diff suppressed because it is too large
Load Diff
|
@ -1,75 +1,73 @@
|
|||
[tool.poetry]
|
||||
[project]
|
||||
name = "suna"
|
||||
version = "1.0"
|
||||
description = "open source generalist AI Agent"
|
||||
authors = ["marko-kraemer <mail@markokraemer.com>"]
|
||||
authors = [{ name = "marko-kraemer", email = "mail@markokraemer.com" }]
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
homepage = "https://www.suna.so/"
|
||||
repository = "https://github.com/kortix-ai/suna"
|
||||
license = { text = "Apache-2.0" }
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: Apache-2.0 License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
]
|
||||
requires-python = "==3.11.10"
|
||||
dependencies = [
|
||||
"python-dotenv==1.0.1",
|
||||
"litellm==1.66.1",
|
||||
"click==8.1.7",
|
||||
"questionary==2.0.1",
|
||||
"requests==2.32.3",
|
||||
"packaging==24.1",
|
||||
"setuptools==75.3.0",
|
||||
"pytest==8.3.3",
|
||||
"pytest-asyncio==0.24.0",
|
||||
"asyncio==3.4.3",
|
||||
"altair==4.2.2",
|
||||
"prisma==0.15.0",
|
||||
"fastapi==0.115.12",
|
||||
"uvicorn==0.27.1",
|
||||
"python-multipart==0.0.20",
|
||||
"redis==5.2.1",
|
||||
"upstash-redis==1.3.0",
|
||||
"supabase==2.15.0",
|
||||
"pyjwt==2.10.1",
|
||||
"exa-py==1.9.1",
|
||||
"e2b-code-interpreter==1.2.0",
|
||||
"certifi==2024.2.2",
|
||||
"python-ripgrep==0.0.6",
|
||||
"daytona-sdk==0.21.0a4",
|
||||
"daytona-api-client==0.21.0a1",
|
||||
"daytona-api-client-async==0.21.0a1",
|
||||
"boto3==1.37.3",
|
||||
"openai==1.72.0",
|
||||
"nest-asyncio==1.6.0",
|
||||
"vncdotool==1.2.0",
|
||||
"tavily-python==0.5.4",
|
||||
"pytesseract==0.3.13",
|
||||
"stripe==12.0.1",
|
||||
"dramatiq==1.17.1",
|
||||
"pika==1.3.2",
|
||||
"prometheus-client==0.21.1",
|
||||
"langfuse==2.60.5",
|
||||
"Pillow==10.0.0",
|
||||
"mcp==1.0.0",
|
||||
"httpx==0.28.0",
|
||||
"aiohttp==3.12.0",
|
||||
"email-validator==2.0.0",
|
||||
"mailtrap==2.0.1",
|
||||
"sentry-sdk[fastapi]==2.29.1",
|
||||
"gunicorn>=23.0.0",
|
||||
]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
python-dotenv = "1.0.1"
|
||||
litellm = "1.66.1"
|
||||
click = "8.1.7"
|
||||
questionary = "2.0.1"
|
||||
requests = "^2.31.0"
|
||||
packaging = "24.1"
|
||||
setuptools = "75.3.0"
|
||||
pytest = "8.3.3"
|
||||
pytest-asyncio = "0.24.0"
|
||||
asyncio = "3.4.3"
|
||||
altair = "4.2.2"
|
||||
prisma = "0.15.0"
|
||||
fastapi = "0.110.0"
|
||||
uvicorn = "0.27.1"
|
||||
python-multipart = "0.0.20"
|
||||
redis = "5.2.1"
|
||||
upstash-redis = "1.3.0"
|
||||
supabase = "^2.15.0"
|
||||
pyjwt = "2.10.1"
|
||||
exa-py = "^1.9.1"
|
||||
e2b-code-interpreter = "^1.2.0"
|
||||
certifi = "2024.2.2"
|
||||
python-ripgrep = "0.0.6"
|
||||
daytona_sdk = "^0.20.2"
|
||||
boto3 = "^1.34.0"
|
||||
openai = "^1.72.0"
|
||||
nest-asyncio = "^1.6.0"
|
||||
vncdotool = "^1.2.0"
|
||||
tavily-python = "^0.5.4"
|
||||
pytesseract = "^0.3.13"
|
||||
stripe = "^12.0.1"
|
||||
dramatiq = "^1.17.1"
|
||||
pika = "^1.3.2"
|
||||
prometheus-client = "^0.21.1"
|
||||
langfuse = "^2.60.5"
|
||||
Pillow = "^10.0.0"
|
||||
mcp = "^1.0.0"
|
||||
sentry-sdk = {extras = ["fastapi"], version = "^2.29.1"}
|
||||
httpx = "^0.28.0"
|
||||
aiohttp = "^3.9.0"
|
||||
email-validator = "^2.0.0"
|
||||
mailtrap = "^2.0.1"
|
||||
[project.urls]
|
||||
homepage = "https://www.suna.so/"
|
||||
repository = "https://github.com/kortix-ai/suna"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
[project.scripts]
|
||||
agentpress = "agentpress.cli:main"
|
||||
|
||||
[[tool.poetry.packages]]
|
||||
include = "agentpress"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
daytona-sdk = "^0.20.2"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
[tool.uv]
|
||||
package = false
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
python-dotenv==1.0.1
|
||||
litellm==1.66.1
|
||||
click==8.1.7
|
||||
questionary==2.0.1
|
||||
requests>=2.31.0
|
||||
packaging==24.1
|
||||
setuptools==75.3.0
|
||||
pytest==8.3.3
|
||||
pytest-asyncio==0.24.0
|
||||
asyncio==3.4.3
|
||||
altair==4.2.2
|
||||
prisma==0.15.0
|
||||
fastapi==0.110.0
|
||||
uvicorn==0.27.1
|
||||
python-multipart==0.0.20
|
||||
redis==5.2.1
|
||||
upstash-redis==1.3.0
|
||||
supabase>=2.15.0
|
||||
pyjwt==2.10.1
|
||||
exa-py>=1.9.1
|
||||
e2b-code-interpreter>=1.2.0
|
||||
certifi==2024.2.2
|
||||
python-ripgrep==0.0.6
|
||||
daytona-sdk==0.20.2
|
||||
boto3>=1.34.0
|
||||
openai>=1.72.0
|
||||
nest-asyncio>=1.6.0
|
||||
vncdotool>=1.2.0
|
||||
tavily-python>=0.5.4
|
||||
pytesseract==0.3.13
|
||||
stripe>=12.0.1
|
||||
dramatiq>=1.17.1
|
||||
pika>=1.3.2
|
||||
prometheus-client>=0.21.1
|
||||
langfuse==2.60.5
|
||||
httpx>=0.24.0
|
||||
Pillow>=10.0.0
|
||||
sentry-sdk[fastapi]>=2.29.1
|
||||
mcp>=1.0.0
|
||||
mcp_use>=1.0.0
|
||||
aiohttp>=3.9.0
|
||||
email-validator>=2.0.0
|
||||
mailtrap>=2.0.1
|
File diff suppressed because it is too large
Load Diff
|
@ -63,12 +63,15 @@ Obtain the following API keys:
|
|||
|
||||
Ensure the following tools are installed on your system:
|
||||
|
||||
- **[Git](https://git-scm.com/downloads)**
|
||||
- **[Docker](https://docs.docker.com/get-docker/)**
|
||||
- **[Python 3.11](https://www.python.org/downloads/)**
|
||||
- **[Poetry](https://python-poetry.org/docs/#installation)**
|
||||
- **[Node.js & npm](https://nodejs.org/en/download/)**
|
||||
- **[Supabase CLI](https://supabase.com/docs/guides/local-development/cli/getting-started)**
|
||||
- **[Git](https://git-scm.com/downloads)**
|
||||
- **[Python 3.11](https://www.python.org/downloads/)**
|
||||
|
||||
For manual setup, you'll also need:
|
||||
|
||||
- **[uv](https://docs.astral.sh/uv/)**
|
||||
- **[Node.js & npm](https://nodejs.org/en/download/)**
|
||||
|
||||
## Installation Steps
|
||||
|
||||
|
@ -212,6 +215,8 @@ This method requires you to start each component separately:
|
|||
|
||||
```bash
|
||||
docker compose up redis rabbitmq -d
|
||||
# or
|
||||
python start.py # Use the same to stop it later
|
||||
```
|
||||
|
||||
2. Start the frontend (in one terminal):
|
||||
|
@ -225,14 +230,14 @@ npm run dev
|
|||
|
||||
```bash
|
||||
cd backend
|
||||
poetry run python3.11 api.py
|
||||
uv run python api.py
|
||||
```
|
||||
|
||||
4. Start the worker (in one more terminal):
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
poetry run python3.11 -m dramatiq run_agent_background
|
||||
uv run python -m dramatiq run_agent_background
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
@ -273,11 +278,11 @@ npm run dev
|
|||
|
||||
# Backend logs (manual setup)
|
||||
cd backend
|
||||
poetry run python3.11 api.py
|
||||
uv run python api.py
|
||||
|
||||
# Worker logs (manual setup)
|
||||
cd backend
|
||||
poetry run python3.11 -m dramatiq run_agent_background
|
||||
uv run python -m dramatiq run_agent_background
|
||||
```
|
||||
|
||||
---
|
||||
|
|
Loading…
Reference in New Issue