mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
## Block Development SDK - Simplifying Block Creation ### Problem Currently, creating a new block requires manual updates to **5+ files** scattered across the codebase: - `backend/data/block_cost_config.py` - Manually add block costs - `backend/integrations/credentials_store.py` - Add default credentials - `backend/integrations/providers.py` - Register new providers - `backend/integrations/oauth/__init__.py` - Register OAuth handlers - `backend/integrations/webhooks/__init__.py` - Register webhook managers This creates significant friction for developers, increases the chance of configuration errors, and makes the platform difficult to scale. ### Solution This PR introduces a **Block Development SDK** that provides: - Single import for all block development needs: `from backend.sdk import *` - Automatic registration of all block configurations - Zero external file modifications required - Provider-based configuration with inheritance ### Changes 🏗️ #### 1. **New SDK Module** (`backend/sdk/`) - **`__init__.py`**: Unified exports of 68+ block development components - **`registry.py`**: Central auto-registration system for all block configurations - **`builder.py`**: `ProviderBuilder` class for fluent provider configuration - **`provider.py`**: Provider configuration management - **`cost_integration.py`**: Automatic cost application system #### 2. **Provider Builder Pattern** ```python # Configure once, use everywhere my_provider = ( ProviderBuilder("my-service") .with_api_key("MY_SERVICE_API_KEY", "My Service API Key") .with_base_cost(5, BlockCostType.RUN) .build() ) ``` #### 3. **Automatic Cost System** - Provider base costs automatically applied to all blocks using that provider - Override with `@cost` decorator for block-specific pricing - Tiered pricing support with cost filters #### 4. **Dynamic Provider Support** - Modified `ProviderName` enum to accept any string via `_missing_` method - No more manual enum updates for new providers #### 5. **Application Integration** - Added `sync_all_provider_costs()` to `initialize_blocks()` for automatic cost registration - Maintains full backward compatibility with existing blocks #### 6. **Comprehensive Examples** (`backend/blocks/examples/`) - `simple_example_block.py` - Basic block structure - `example_sdk_block.py` - Provider with credentials - `cost_example_block.py` - Various cost patterns - `advanced_provider_example.py` - Custom API clients - `example_webhook_sdk_block.py` - Webhook configuration #### 7. **Extensive Testing** - 6 new test modules with 30+ test cases - Integration tests for all SDK features - Cost calculation verification - Provider registration tests ### Before vs After **Before SDK:** ```python # 1. Multiple complex imports from backend.data.block import Block, BlockCategory, BlockOutput from backend.data.model import SchemaField, CredentialsField # ... many more imports # 2. Update block_cost_config.py BLOCK_COSTS[MyBlock] = [BlockCost(...)] # 3. Update credentials_store.py DEFAULT_CREDENTIALS.append(...) # 4. Update providers.py enum # 5. Update oauth/__init__.py # 6. Update webhooks/__init__.py ``` **After SDK:** ```python from backend.sdk import * # Everything configured in one place my_provider = ( ProviderBuilder("my-service") .with_api_key("MY_API_KEY", "My API Key") .with_base_cost(10, BlockCostType.RUN) .build() ) class MyBlock(Block): class Input(BlockSchema): credentials: CredentialsMetaInput = my_provider.credentials_field() data: String = SchemaField(description="Input data") class Output(BlockSchema): result: String = SchemaField(description="Result") # That's it\! No external files to modify ``` ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Created new blocks using SDK pattern with provider configuration - [x] Verified automatic cost registration for provider-based blocks - [x] Tested cost override with @cost decorator - [x] Confirmed custom providers work without enum modifications - [x] Verified all example blocks execute correctly - [x] Tested backward compatibility with existing blocks - [x] Ran all SDK tests (30+ tests, all passing) - [x] Created blocks with credentials and verified authentication - [x] Tested webhook block configuration - [x] Verified application startup with auto-registration #### For configuration changes: - [x] `.env.example` is updated or already compatible with my changes (no changes needed) - [x] `docker-compose.yml` is updated or already compatible with my changes (no changes needed) - [x] I have included a list of my configuration changes in the PR description (under **Changes**) ### Impact - **Developer Experience**: Block creation time reduced from hours to minutes - **Maintainability**: All block configuration in one place - **Scalability**: Support hundreds of blocks without enum updates - **Type Safety**: Full IDE support with proper type hints - **Testing**: Easier to test blocks in isolation --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Abhimanyu Yadav <122007096+Abhi1992002@users.noreply.github.com>
229 lines
5.5 KiB
YAML
229 lines
5.5 KiB
YAML
name: AutoGPT Platform - Frontend CI
|
|
|
|
on:
|
|
push:
|
|
branches: [master, dev]
|
|
paths:
|
|
- ".github/workflows/platform-frontend-ci.yml"
|
|
- "autogpt_platform/frontend/**"
|
|
pull_request:
|
|
paths:
|
|
- ".github/workflows/platform-frontend-ci.yml"
|
|
- "autogpt_platform/frontend/**"
|
|
merge_group:
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
working-directory: autogpt_platform/frontend
|
|
|
|
jobs:
|
|
setup:
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
cache-key: ${{ steps.cache-key.outputs.key }}
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "21"
|
|
|
|
- name: Enable corepack
|
|
run: corepack enable
|
|
|
|
- name: Generate cache key
|
|
id: cache-key
|
|
run: echo "key=${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Cache dependencies
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.pnpm-store
|
|
key: ${{ steps.cache-key.outputs.key }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pnpm-
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
lint:
|
|
runs-on: ubuntu-latest
|
|
needs: setup
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "21"
|
|
|
|
- name: Enable corepack
|
|
run: corepack enable
|
|
|
|
- name: Restore dependencies cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.pnpm-store
|
|
key: ${{ needs.setup.outputs.cache-key }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pnpm-
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Run lint
|
|
run: pnpm lint
|
|
|
|
type-check:
|
|
runs-on: ubuntu-latest
|
|
needs: setup
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "21"
|
|
|
|
- name: Enable corepack
|
|
run: corepack enable
|
|
|
|
- name: Restore dependencies cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.pnpm-store
|
|
key: ${{ needs.setup.outputs.cache-key }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pnpm-
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Run tsc check
|
|
run: pnpm type-check
|
|
|
|
chromatic:
|
|
runs-on: ubuntu-latest
|
|
needs: setup
|
|
# Only run on dev branch pushes or PRs targeting dev
|
|
if: github.ref == 'refs/heads/dev' || github.base_ref == 'dev'
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "21"
|
|
|
|
- name: Enable corepack
|
|
run: corepack enable
|
|
|
|
- name: Restore dependencies cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.pnpm-store
|
|
key: ${{ needs.setup.outputs.cache-key }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pnpm-
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Run Chromatic
|
|
uses: chromaui/action@latest
|
|
with:
|
|
projectToken: chpt_9e7c1a76478c9c8
|
|
onlyChanged: true
|
|
workingDir: autogpt_platform/frontend
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
exitOnceUploaded: true
|
|
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
needs: setup
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
browser: [chromium, webkit]
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: "21"
|
|
|
|
- name: Enable corepack
|
|
run: corepack enable
|
|
|
|
- name: Free Disk Space (Ubuntu)
|
|
uses: jlumbroso/free-disk-space@main
|
|
with:
|
|
large-packages: false # slow
|
|
docker-images: false # limited benefit
|
|
|
|
- name: Copy default supabase .env
|
|
run: |
|
|
cp ../.env.example ../.env
|
|
|
|
- name: Copy backend .env
|
|
run: |
|
|
cp ../backend/.env.example ../backend/.env
|
|
|
|
- name: Run docker compose
|
|
run: |
|
|
docker compose -f ../docker-compose.yml up -d
|
|
|
|
- name: Restore dependencies cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.pnpm-store
|
|
key: ${{ needs.setup.outputs.cache-key }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pnpm-
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Setup .env
|
|
run: cp .env.example .env
|
|
|
|
- name: Build frontend
|
|
run: pnpm build --turbo
|
|
# uses Turbopack, much faster and safe enough for a test pipeline
|
|
|
|
- name: Install Browser '${{ matrix.browser }}'
|
|
run: pnpm playwright install --with-deps ${{ matrix.browser }}
|
|
|
|
- name: Run Playwright tests
|
|
run: pnpm test:no-build --project=${{ matrix.browser }}
|
|
env:
|
|
BROWSER_TYPE: ${{ matrix.browser }}
|
|
|
|
- name: Print Final Docker Compose logs
|
|
if: always()
|
|
run: docker compose -f ../docker-compose.yml logs
|
|
|
|
- uses: actions/upload-artifact@v4
|
|
if: ${{ !cancelled() }}
|
|
with:
|
|
name: playwright-report-${{ matrix.browser }}
|
|
path: playwright-report/
|
|
retention-days: 30
|