Skip to content

Latest commit

Β 

History

History
480 lines (405 loc) Β· 21.1 KB

File metadata and controls

480 lines (405 loc) Β· 21.1 KB

Development Guide

Instructions for setting up a development environment and contributing to OpenForge.

Prerequisites

  • Node.js 22+ (for frontend)
  • Python 3.11+ (for backend)
  • Docker and Docker Compose (for databases and supporting services)

Development Setup

OpenForge provides a development Docker Compose configuration with hot reloading.

Option 1: Docker Compose (Recommended)

# 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 -d

This 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

Option 2: Manual Setup

Start only the database services via Docker:

docker compose up postgres qdrant redis -d

Then 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 8001

Project Structure

OpenForge/
β”œβ”€β”€ 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

Code Placement Rules

Backend

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

Frontend

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.

Tool Server

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 BaseTool abstract 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

Domain Development Guide

Adding a New Domain

  1. 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
    
  2. Add database models to backend/openforge/db/models.py

  3. Create an Alembic migration:

    cd backend
    alembic revision --autogenerate -m "add my_domain tables"
  4. Register the router in backend/openforge/domains/router_registry.py

Existing Domains

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 Execution

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.

Tool Development Guide

Adding a New Tool

  1. Create a directory under tool_server/tools/:

    tool_server/tools/my_category/__init__.py
    
  2. 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()]
  3. Restart the tool server:

    docker compose build tool-server && docker compose up -d tool-server
  4. Sync tools in the backend:

    curl -X POST http://localhost:3100/api/v1/tools/sync

Settings Tab Pattern

To add a new settings tab:

  1. Create a tab component in frontend/src/pages/settings/{tab_name}/:

    frontend/src/pages/settings/my_tab/
    └── MyTab.tsx
    
  2. Register the tab in frontend/src/pages/settings/constants.ts:

    • Add to the SETTINGS_TABS array
    • Add to the toSettingsTab normalization function if needed
  3. Add the tab to the settings router in frontend/src/pages/settings/index.tsx

  4. Add the tab to the layout in frontend/src/pages/settings/SettingsLayout.tsx

Database Migrations

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 head

Testing

Backend Tests

cd backend
python -m pytest tests/ -v

Key test directories:

  • tests/architecture/ β€” Schema presence, regression, release smoke tests
  • tests/domains/agents/ β€” Agent blueprint, compiler, service tests
  • tests/domains/automations/ β€” Automation service tests
  • tests/runtime/ β€” Tool loop, chat handler, agent registry tests

Frontend Tests

cd frontend
npm test

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Open an issue first for significant changes to discuss the approach
  2. Keep changes focused β€” one feature or fix per pull request
  3. Follow existing patterns β€” match the code style and architecture of the surrounding code
  4. Test your changes β€” ensure the application works end-to-end
  5. Write clear commit messages β€” describe what changed and why

Pull Request Process

  1. Fork the repository
  2. Create a feature branch from main
  3. Make your changes following the code placement rules above
  4. Test locally with docker compose -f docker-compose.dev.yml up
  5. Submit a pull request with a clear description of the changes

For architecture details, see Architecture. For deployment instructions, see Deployment.