Instructions for setting up a development environment and contributing to OpenForge.
- Node.js 22+ (for frontend)
- Python 3.11+ (for backend)
- Docker and Docker Compose (for databases and supporting services)
OpenForge provides a development Docker Compose configuration with hot reloading.
# Clone the repository
git clone https://github.com/OpenForge-AI/OpenForge.git
cd OpenForge
# Configure environment
cp .env.example .env
# Edit .env and set DB_PASSWORD
# Start in development mode
docker compose -f docker-compose.dev.yml up -dThis starts all services with live reloading:
- Backend β Auto-reloads on Python file changes (port 3000)
- Frontend β Vite dev server with HMR (port 5173, proxied through 3100)
- Tool Server β Auto-reloads on file changes (port 8001)
- Databases β PostgreSQL, Qdrant, Redis, SearXNG
Start only the database services via Docker:
docker compose up postgres qdrant redis -dThen run the backend and frontend separately:
# Backend (terminal 1)
cd backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn openforge.main:app --reload --port 3000
# Frontend (terminal 2)
cd frontend
npm install
npm run dev # -> http://localhost:5173 (proxies /api to port 3000)
# Tool Server (terminal 3)
cd tool_server
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reload --port 8001OpenForge/
βββ backend/ # Python backend application
β βββ requirements.txt
β βββ openforge/
β βββ main.py # FastAPI application entry point
β βββ api/ # HTTP route handlers (thin layer)
β βββ common/ # Shared utilities and configuration
β β βββ config/ # Centralized settings
β β βββ crypto/ # Encryption utilities
β β βββ errors/ # Exception types
β βββ core/ # Core business logic
β β βββ embedding.py # Text and image embedding
β β βββ llm_gateway.py # Unified LLM interface
β β βββ search_engine.py # Hybrid search (dense + sparse)
β β βββ context_assembler.py # Token budget management
β β βββ prompt_resolution.py # Prompt template resolution
β βββ db/ # Database layer
β β βββ models.py # SQLAlchemy models (all entities)
β β βββ postgres.py # Database engine and migrations
β β βββ qdrant_client.py # Vector database client
β β βββ redis_client.py # Redis client
β β βββ migrations/ # Alembic migration scripts
β βββ domains/ # Domain-driven business logic
β β βββ agents/ # Structured agent definitions
β β β βββ compiled_spec.py # AgentRuntimeConfig builder
β β β βββ service.py # Agent CRUD + version snapshots
β β β βββ router.py # API routes (incl. version endpoints)
β β β βββ schemas.py # Pydantic schemas (structured fields)
β β βββ automations/ # DAG workflow definitions
β β β βββ blueprint.py # Trigger, budget, output config
β β β βββ compiler.py # Automation compilation
β β β βββ compiled_spec.py # Compiled automation spec
β β β βββ graph_validation.py # DAG structure validation
β β β βββ service.py # Automation CRUD
β β β βββ router.py # API routes
β β β βββ schemas.py # Pydantic schemas
β β βββ deployments/ # Live automation instances
β β β βββ service.py # Deployment lifecycle management
β β β βββ router.py # API routes
β β β βββ schemas.py # Pydantic schemas
β β βββ knowledge/ # Knowledge management
β β βββ retrieval/ # Search and evidence
β β βββ runs/ # Run execution tracking
β β βββ outputs/ # Versioned output artifacts
β β β βββ versioning.py # Version management
β β β βββ lineage.py # Provenance tracking
β β β βββ publishing.py # Publishing logic
β β β βββ sinks.py # Output destination routing
β β β βββ service.py # Output CRUD
β β βββ common/ # Shared domain utilities
β βββ integrations/ # External integrations
β β βββ tools/ # Tool server HTTP client
β βββ middleware/ # HTTP middleware (auth)
β βββ runtime/ # Execution engines
β β βββ chat_handler.py # Interactive chat execution (global, workspace-agnostic)
β β βββ agent_executor.py # Background agent execution
β β βββ graph_executor.py # DAG workflow execution for deployments
β β βββ tool_loop.py # LLM + tool dispatch cycle
β β βββ agent_registry.py # Agent resolution at runtime
β β βββ input_extraction.py # Extract parameter values from chat messages
β β βββ deployment_scheduler.py # Celery Beat polling for deployment triggers
β β βββ handoff_engine.py # Agent-to-agent delegation
β β βββ provider_config.py # LLM provider resolution
β β βββ hitl.py # Human-in-the-loop approvals
β β βββ policy.py # Tool permission engine
β β βββ lifecycle.py # Run state transitions
β β βββ events.py # Runtime event types
β β βββ event_publisher.py # Event broadcasting
β β βββ checkpoint_store.py # Durable state snapshots
β β βββ mission_executor.py # Autonomous mission OODA cycle execution
β β βββ mission_scheduler.py # Mission cadence scheduling
β β βββ sink_handlers.py # Sink type execution handlers
β β βββ prompt_context.py # Context-aware preamble/postamble (CHAT vs AUTOMATION vs MISSION)
β β βββ template_engine/ # Template engine (parser, renderer, functions, types)
β βββ services/ # Application services
β β βββ llm_service.py # LLM provider management
β β βββ knowledge_processing_service.py # Knowledge pipeline
β β βββ conversation_service.py # Chat management
β β βββ workspace_service.py # Workspace management
β β βββ automation_config.py # Automation config service
β β βββ config_service.py # Configuration store
β β βββ mcp_service.py # MCP server integration
β βββ worker/ # Celery background tasks
β βββ autoscale.py # Logarithmic worker autoscaler
β βββ celery_app.py # Celery configuration
β βββ tasks.py # Task definitions
β
βββ frontend/ # React frontend application
β βββ package.json
β βββ vite.config.ts
β βββ tailwind.config.js
β βββ src/
β βββ main.tsx # App entry point with routing
β βββ index.css # Global styles and theme
β βββ components/ # Shared UI components
β β βββ shared/ # Reusable business components (PromptTemplateEditor, ConfirmModal, etc.)
β β βββ layout/ # Shell and navigation
β β βββ agents/ # Agent config siderail with accordion sections
β β βββ automations/ # Graph editor, node palette, agent nodes
β β βββ chat/ # Chat UI (composer, timeline, tool cards, streaming, HITL)
β β βββ knowledge/ # Knowledge editors and cards
β β βββ search/ # Search interface
β β βββ ui/ # Radix-based primitives
β βββ pages/ # Page components
β β βββ AgentsPage.tsx # Agent list (table view)
β β βββ AgentDetailPage.tsx # Agent detail (create/view/edit modes)
β β βββ AgentChatPage.tsx # Global chat interface (workspace-agnostic)
β β βββ AutomationsPage.tsx # Automation list
β β βββ AutomationDetailPage.tsx # Automation detail with graph editor
β β βββ DeploymentsPage.tsx # Deployment list
β β βββ DeploymentDetailPage.tsx # Deployment detail
β β βββ MissionsPage.tsx # Mission list
β β βββ MissionDetailPage.tsx # Mission detail with cycle tracking
β β βββ SinksPage.tsx # Sink list
β β βββ SinkDetailPage.tsx # Sink configuration
β β βββ RunsPage.tsx # Run list
β β βββ RunDetailPage.tsx # Run detail
β β βββ OutputsPage.tsx # Output list
β β βββ OutputDetailPage.tsx # Output detail with versioning
β β βββ DashboardPage.tsx # Workspace dashboard
β β βββ SearchPage.tsx # Search
β β βββ settings/ # Settings sub-pages
β βββ features/ # Domain-specific feature modules
β β βββ agents/ # Agent components and hooks
β β βββ automations/ # Automation components and hooks
β β βββ runs/ # Run monitoring
β β βββ outputs/ # Output management
β β βββ artifacts/ # Legacy artifact support
β β βββ retrieval/ # Evidence building
β β βββ knowledge/ # Knowledge queries
β βββ hooks/ # Custom React hooks
β βββ stores/ # Zustand state management
β βββ types/ # TypeScript type definitions
β β βββ agents.ts # Agent types
β β βββ automations.ts # Automation types
β β βββ runs.ts # Run types
β β βββ ...
β βββ lib/ # Utilities and API client
β βββ api.ts # API endpoint definitions
β βββ routes.ts # Route definitions
β βββ productVocabulary.ts # Product term mapping
β βββ formatters.ts # Data formatting utilities
β
βββ tool_server/ # Tool execution microservice
β βββ main.py # FastAPI entry point
β βββ protocol.py # BaseTool abstract interface
β βββ registry.py # Tool auto-discovery and aliasing
β βββ security.py # Path/command/URL validation
β βββ config.py # Tool server settings
β βββ content_boundary.py # Untrusted content wrapping
β βββ requirements.txt
β βββ tools/ # Tool implementations
β βββ filesystem/ # File operations (7 tools)
β βββ shell/ # Command execution (2 tools)
β βββ git/ # Version control (6 tools)
β βββ language/ # Code analysis (4 tools)
β βββ workspace/ # Knowledge access (4 tools)
β βββ memory/ # Agent memory (3 tools)
β βββ http/ # Web access (4 tools)
β βββ agent/ # Agent delegation + chat access (3 tools)
β βββ task/ # Task management (3 tools)
β βββ skills/ # Skill management (5 tools)
β
βββ docker/ # Docker build files
β βββ Dockerfile # Production (multi-stage: frontend build + backend)
β βββ Dockerfile.worker # Celery worker
β βββ Dockerfile.tool-server # Tool server
β βββ Dockerfile.dev.backend # Development backend (live reload)
β βββ Dockerfile.dev.frontend # Development frontend (Vite HMR)
β βββ searxng/ # SearXNG configuration
β
βββ docker-compose.yml # Production compose
βββ docker-compose.dev.yml # Development compose (hot reload)
βββ .env.example # Environment variable template
βββ docs/ # Documentation
| What | Where |
|---|---|
| Shared utilities | backend/openforge/common/ |
| Domain business logic | backend/openforge/domains/{domain}/service.py |
| API route handlers | backend/openforge/api/{resource}.py (thin β delegates to services) |
| Agent execution logic | backend/openforge/runtime/ |
| External integrations | backend/openforge/integrations/ |
| Database models | backend/openforge/db/models.py |
Rules:
- API routes should be thin β validate input, call a service, return the response
- Domain services should not import from other domains directly
- New retrieval logic goes in
domains/retrieval/ - Meaningful outputs should be modeled as outputs (not ad-hoc tables)
- Agent execution must flow through agent_registry for spec resolution
| What | Where |
|---|---|
| Page components | frontend/src/pages/ (thin shells) |
| Domain feature modules | frontend/src/features/{domain}/ |
| Shared UI components | frontend/src/components/shared/ |
| Layout components | frontend/src/components/layout/ |
| API calls | frontend/src/lib/api.ts |
| Custom hooks | frontend/src/hooks/ |
| Type definitions | frontend/src/types/ |
Rules:
- Pages compose feature components, they don't contain business logic
- API calls are centralized in
lib/api.ts - Feature modules contain domain-specific components, hooks, and types
- Shared components are domain-agnostic
- Layout components are presentational only (no business logic)
- Domain routes: Agents, Chat, Automations, Deployments, Missions, Sinks, Runs, Outputs are top-level (workspace-agnostic). Knowledge and Search are workspace-scoped.
| What | Where |
|---|---|
| New tool category | tool_server/tools/{category}/ with __init__.py exporting TOOLS list |
| Tool implementation | Extends BaseTool from protocol.py |
| Security rules | tool_server/security.py |
| Tool aliases | tool_server/registry.py |
Rules:
- All tools must implement the
BaseToolabstract class - Tools are auto-discovered β just add a new directory with
__init__.py - HTTP calls must use
httpx(aiohttp is not available) - All file paths must be validated against workspace boundaries
- External HTTP responses must be wrapped with the content boundary
-
Create the domain directory:
backend/openforge/domains/my_domain/ βββ __init__.py βββ service.py # Business logic βββ router.py # API routes βββ schemas.py # Pydantic schemas βββ types.py # Domain types -
Add database models to
backend/openforge/db/models.py -
Create an Alembic migration:
cd backend alembic revision --autogenerate -m "add my_domain tables"
-
Register the router in
backend/openforge/domains/router_registry.py
| Domain | Key Files | Notes |
|---|---|---|
| agents | compiled_spec.py, service.py, schemas.py | Structured definitions, version snapshots, runtime config builder |
| automations | compiler.py, graph_validation.py, service.py | DAG workflows with node wiring and validation |
| deployments | service.py, router.py, schemas.py | Live automation instances with triggers and scheduling |
| missions | service.py, router.py, schemas.py | Autonomous goal pursuit with OODA cycles and rubric evaluation |
| sinks | service.py, router.py, schemas.py | Reusable output destinations (log, knowledge, article, REST API, notification) |
| knowledge | (via services layer) | Knowledge types managed by knowledge_processing_service |
| retrieval | service.py | Hybrid search, evidence building |
| runs | service.py | Run tracking, steps, events |
| outputs | versioning.py, lineage.py, sinks.py, publishing.py | Versioned artifacts with provenance |
| common | enums.py | Shared types and enums |
Background agent runs (automations, deployments, handoffs) use agent_executor.execute_agent():
from openforge.runtime.agent_executor import execute_agent
result = await execute_agent(
spec,
{"message": "..."},
db=db,
workspace_id=workspace_id,
event_publisher=event_publisher,
tool_dispatcher=tool_dispatcher,
llm_gateway=llm_gateway,
)This creates a RunModel, builds messages from the agent spec, loads tools, resolves the LLM provider, and calls execute_tool_loop() β the same engine used by interactive chat.
-
Create a directory under
tool_server/tools/:tool_server/tools/my_category/__init__.py -
Implement one or more tools:
from protocol import BaseTool, ToolResult, ToolContext class MyTool(BaseTool): id = "my_category.my_tool" category = "my_category" display_name = "My Tool" description = "What this tool does" input_schema = { "type": "object", "properties": { "param1": {"type": "string", "description": "..."} }, "required": ["param1"] } risk_level = "low" # low, medium, high, critical async def execute(self, params: dict, context: ToolContext) -> ToolResult: # Implementation here return ToolResult(success=True, output="result") TOOLS = [MyTool()]
-
Restart the tool server:
docker compose build tool-server && docker compose up -d tool-server -
Sync tools in the backend:
curl -X POST http://localhost:3100/api/v1/tools/sync
To add a new settings tab:
-
Create a tab component in
frontend/src/pages/settings/{tab_name}/:frontend/src/pages/settings/my_tab/ βββ MyTab.tsx -
Register the tab in
frontend/src/pages/settings/constants.ts:- Add to the
SETTINGS_TABSarray - Add to the
toSettingsTabnormalization function if needed
- Add to the
-
Add the tab to the settings router in
frontend/src/pages/settings/index.tsx -
Add the tab to the layout in
frontend/src/pages/settings/SettingsLayout.tsx
Migrations run automatically on startup. To create a new migration manually:
cd backend
alembic revision --autogenerate -m "description of change"To run migrations manually:
cd backend
alembic upgrade headcd backend
python -m pytest tests/ -vKey test directories:
tests/architecture/β Schema presence, regression, release smoke teststests/domains/agents/β Agent blueprint, compiler, service teststests/domains/automations/β Automation service teststests/runtime/β Tool loop, chat handler, agent registry tests
cd frontend
npm testContributions are welcome! Please follow these guidelines:
- Open an issue first for significant changes to discuss the approach
- Keep changes focused β one feature or fix per pull request
- Follow existing patterns β match the code style and architecture of the surrounding code
- Test your changes β ensure the application works end-to-end
- Write clear commit messages β describe what changed and why
- Fork the repository
- Create a feature branch from
main - Make your changes following the code placement rules above
- Test locally with
docker compose -f docker-compose.dev.yml up - Submit a pull request with a clear description of the changes
For architecture details, see Architecture. For deployment instructions, see Deployment.