Rename store_media_file() return_format options to make intent clear: - "local_path" -> "for_local_processing" (ffmpeg, MoviePy, PIL) - "data_uri" -> "for_external_api" (Replicate, OpenAI APIs) - "workspace_ref" -> "for_block_output" (auto-adapts to context) The "for_block_output" format now gracefully handles both contexts: - CoPilot (has workspace): returns workspace:// reference - Graph execution (no workspace): falls back to data URI This prevents blocks from failing in graph execution while still providing workspace persistence in CoPilot. Also adds documentation to CLAUDE.md, new_blocks.md, and block-sdk-guide.md explaining when to use each format. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Repository Overview
AutoGPT Platform is a monorepo containing:
- Backend (
/backend): Python FastAPI server with async support - Frontend (
/frontend): Next.js React application - Shared Libraries (
/autogpt_libs): Common Python utilities
Essential Commands
Backend Development
# Install dependencies
cd backend && poetry install
# Run database migrations
poetry run prisma migrate dev
# Start all services (database, redis, rabbitmq, clamav)
docker compose up -d
# Run the backend server
poetry run serve
# Run tests
poetry run test
# Run specific test
poetry run pytest path/to/test_file.py::test_function_name
# Run block tests (tests that validate all blocks work correctly)
poetry run pytest backend/blocks/test/test_block.py -xvs
# Run tests for a specific block (e.g., GetCurrentTimeBlock)
poetry run pytest 'backend/blocks/test/test_block.py::test_available_blocks[GetCurrentTimeBlock]' -xvs
# Lint and format
# prefer format if you want to just "fix" it and only get the errors that can't be autofixed
poetry run format # Black + isort
poetry run lint # ruff
More details can be found in TESTING.md
Creating/Updating Snapshots
When you first write a test or when the expected output changes:
poetry run pytest path/to/test.py --snapshot-update
⚠️ Important: Always review snapshot changes before committing! Use git diff to verify the changes are expected.
Frontend Development
# Install dependencies
cd frontend && pnpm i
# Generate API client from OpenAPI spec
pnpm generate:api
# Start development server
pnpm dev
# Run E2E tests
pnpm test
# Run Storybook for component development
pnpm storybook
# Build production
pnpm build
# Format and lint
pnpm format
# Type checking
pnpm types
📖 Complete Guide: See /frontend/CONTRIBUTING.md and /frontend/.cursorrules for comprehensive frontend patterns.
Key Frontend Conventions:
- Separate render logic from data/behavior in components
- Use generated API hooks from
@/app/api/__generated__/endpoints/ - Use function declarations (not arrow functions) for components/handlers
- Use design system components from
src/components/(atoms, molecules, organisms) - Only use Phosphor Icons
- Never use
src/components/__legacy__/*or deprecatedBackendAPI
Architecture Overview
Backend Architecture
- API Layer: FastAPI with REST and WebSocket endpoints
- Database: PostgreSQL with Prisma ORM, includes pgvector for embeddings
- Queue System: RabbitMQ for async task processing
- Execution Engine: Separate executor service processes agent workflows
- Authentication: JWT-based with Supabase integration
- Security: Cache protection middleware prevents sensitive data caching in browsers/proxies
Frontend Architecture
- Framework: Next.js 15 App Router (client-first approach)
- Data Fetching: Type-safe generated API hooks via Orval + React Query
- State Management: React Query for server state, co-located UI state in components/hooks
- Component Structure: Separate render logic (
.tsx) from business logic (use*.tshooks) - Workflow Builder: Visual graph editor using @xyflow/react
- UI Components: shadcn/ui (Radix UI primitives) with Tailwind CSS styling
- Icons: Phosphor Icons only
- Feature Flags: LaunchDarkly integration
- Error Handling: ErrorCard for render errors, toast for mutations, Sentry for exceptions
- Testing: Playwright for E2E, Storybook for component development
Key Concepts
- Agent Graphs: Workflow definitions stored as JSON, executed by the backend
- Blocks: Reusable components in
/backend/blocks/that perform specific tasks - Integrations: OAuth and API connections stored per user
- Store: Marketplace for sharing agent templates
- Virus Scanning: ClamAV integration for file upload security
Testing Approach
- Backend uses pytest with snapshot testing for API responses
- Test files are colocated with source files (
*_test.py) - Frontend uses Playwright for E2E tests
- Component testing via Storybook
Database Schema
Key models (defined in /backend/schema.prisma):
User: Authentication and profile dataAgentGraph: Workflow definitions with version controlAgentGraphExecution: Execution history and resultsAgentNode: Individual nodes in a workflowStoreListing: Marketplace listings for sharing agents
Environment Configuration
Configuration Files
- Backend:
/backend/.env.default(defaults) →/backend/.env(user overrides) - Frontend:
/frontend/.env.default(defaults) →/frontend/.env(user overrides) - Platform:
/.env.default(Supabase/shared defaults) →/.env(user overrides)
Docker Environment Loading Order
.env.defaultfiles provide base configuration (tracked in git).envfiles provide user-specific overrides (gitignored)- Docker Compose
environment:sections provide service-specific overrides - Shell environment variables have highest precedence
Key Points
- All services use hardcoded defaults in docker-compose files (no
${VARIABLE}substitutions) - The
env_filedirective loads variables INTO containers at runtime - Backend/Frontend services use YAML anchors for consistent configuration
- Supabase services (
db/docker/docker-compose.yml) follow the same pattern
Common Development Tasks
Adding a new block:
Follow the comprehensive Block SDK Guide which covers:
- Provider configuration with
ProviderBuilder - Block schema definition
- Authentication (API keys, OAuth, webhooks)
- Testing and validation
- File organization
Quick steps:
- Create new file in
/backend/backend/blocks/ - Configure provider using
ProviderBuilderin_config.py - Inherit from
Blockbase class - Define input/output schemas using
BlockSchema - Implement async
runmethod - Generate unique block ID using
uuid.uuid4() - Test with
poetry run pytest backend/blocks/test/test_block.py
Note: when making many new blocks analyze the interfaces for each of these blocks and picture if they would go well together in a graph based editor or would they struggle to connect productively? ex: do the inputs and outputs tie well together?
If you get any pushback or hit complex block conditions check the new_blocks guide in the docs.
Handling files in blocks with store_media_file():
When blocks need to work with files (images, videos, documents), use store_media_file() from backend.util.file. The return_format parameter determines what you get back:
| Format | Use When | Returns |
|---|---|---|
"for_local_processing" |
Processing with local tools (ffmpeg, MoviePy, PIL) | Local file path (e.g., "image.png") |
"for_external_api" |
Sending content to external APIs (Replicate, OpenAI) | Data URI (e.g., "data:image/png;base64,...") |
"for_block_output" |
Returning output from your block | Smart: workspace:// in CoPilot, data URI in graphs |
Examples:
# INPUT: Need to process file locally with ffmpeg
local_path = await store_media_file(
file=input_data.video,
execution_context=execution_context,
return_format="for_local_processing",
)
# local_path = "video.mp4" - use with Path/ffmpeg/etc
# INPUT: Need to send to external API like Replicate
image_b64 = await store_media_file(
file=input_data.image,
execution_context=execution_context,
return_format="for_external_api",
)
# image_b64 = "data:image/png;base64,iVBORw0..." - send to API
# OUTPUT: Returning result from block
result_url = await store_media_file(
file=generated_image_url,
execution_context=execution_context,
return_format="for_block_output",
)
yield "image_url", result_url
# In CoPilot: result_url = "workspace://abc123"
# In graphs: result_url = "data:image/png;base64,..."
Key points:
for_block_outputis the ONLY format that auto-adapts to execution context- Always use
for_block_outputfor block outputs unless you have a specific reason not to - Never hardcode workspace checks - let
for_block_outputhandle it
Modifying the API:
- Update route in
/backend/backend/server/routers/ - Add/update Pydantic models in same directory
- Write tests alongside the route file
- Run
poetry run testto verify
Frontend guidelines:
See /frontend/CONTRIBUTING.md for complete patterns. Quick reference:
- Pages: Create in
src/app/(platform)/feature-name/page.tsx- Add
usePageName.tshook for logic - Put sub-components in local
components/folder
- Add
- Components: Structure as
ComponentName/ComponentName.tsx+useComponentName.ts+helpers.ts- Use design system components from
src/components/(atoms, molecules, organisms) - Never use
src/components/__legacy__/*
- Use design system components from
- Data fetching: Use generated API hooks from
@/app/api/__generated__/endpoints/- Regenerate with
pnpm generate:api - Pattern:
use{Method}{Version}{OperationName}
- Regenerate with
- Styling: Tailwind CSS only, use design tokens, Phosphor Icons only
- Testing: Add Storybook stories for new components, Playwright for E2E
- Code conventions: Function declarations (not arrow functions) for components/handlers
- Component props should be
interface Props { ... }(not exported) unless the interface needs to be used outside the component - Separate render logic from business logic (component.tsx + useComponent.ts + helpers.ts)
- Colocate state when possible and avoid creating large components, use sub-components ( local
/componentsfolder next to the parent component ) when sensible - Avoid large hooks, abstract logic into
helpers.tsfiles when sensible - Use function declarations for components, arrow functions only for callbacks
- No barrel files or
index.tsre-exports - Do not use
useCallbackoruseMemounless strictly needed - Avoid comments at all times unless the code is very complex
Security Implementation
Cache Protection Middleware:
- Located in
/backend/backend/server/middleware/security.py - Default behavior: Disables caching for ALL endpoints with
Cache-Control: no-store, no-cache, must-revalidate, private - Uses an allow list approach - only explicitly permitted paths can be cached
- Cacheable paths include: static assets (
/static/*,/_next/static/*), health checks, public store pages, documentation - Prevents sensitive data (auth tokens, API keys, user data) from being cached by browsers/proxies
- To allow caching for a new endpoint, add it to
CACHEABLE_PATHSin the middleware - Applied to both main API server and external API applications
Creating Pull Requests
- Create the PR aginst the
devbranch of the repository. - Ensure the branch name is descriptive (e.g.,
feature/add-new-block)/ - Use conventional commit messages (see below)/
- Fill out the .github/PULL_REQUEST_TEMPLATE.md template as the PR description/
- Run the github pre-commit hooks to ensure code quality.
Reviewing/Revising Pull Requests
- When the user runs /pr-comments or tries to fetch them, also run gh api /repos/Significant-Gravitas/AutoGPT/pulls/[issuenum]/reviews to get the reviews
- Use gh api /repos/Significant-Gravitas/AutoGPT/pulls/[issuenum]/reviews/[review_id]/comments to get the review contents
- Use gh api /repos/Significant-Gravitas/AutoGPT/issues/9924/comments to get the pr specific comments
Conventional Commits
Use this format for commit messages and Pull Request titles:
Conventional Commit Types:
feat: Introduces a new feature to the codebasefix: Patches a bug in the codebaserefactor: Code change that neither fixes a bug nor adds a feature; also applies to removing featuresci: Changes to CI configurationdocs: Documentation-only changesdx: Improvements to the developer experience
Recommended Base Scopes:
platform: Changes affecting both frontend and backendfrontendbackendinfrablocks: Modifications/additions of individual blocks
Subscope Examples:
backend/executorbackend/dbfrontend/builder(includes changes to the block UI component)infra/prod
Use these scopes and subscopes for clarity and consistency in commit messages.