ROMA (Recursive Open Meta-Agents)

repository·main·Indexed 26 days ago

https://github.com/sentient-agi/roma

A meta-agent framework for building high-performance, transparent, and extensible multi-agent systems. ROMA uses recursive hierarchical structures to solve complex problems by decomposing them into parallelizable subtasks through a loop involving an Atomizer, Planner, Executors, and Aggregator. The roma-dspy package (v0.1.0) provides a recursive agentic problem solver with support for GEPA (Generative Expectation-Maximization Prompt Optimization), MLflow experiment tracking, and flexible YAML-based configuration profiles.

Tokens
45.4K
Snippets
135
Records
253
Agent score
89%

What's inside ROMA

  1. Overview of ROMA-DSPy Toolkits

    main

    ROMA-DSPy features a toolkit system that allows agents to interact with external systems, execute code, and access data. The architecture supports three main types of toolkits:

    • Native Toolkits: Built-in modules like FileToolkit and CalculatorToolkit.
    • MCP Integration: Connects to any Model Context Protocol (MCP) server.
    • Custom Toolkits: User-defined toolkits.

    Key features include automatic registration with DSPy's tool system, full parameter schemas for LLM selection, execution isolation via file scoping, and optional Parquet storage for large results to manage context usage.

  2. What is ROMA?

    main

    ROMA (Recursive Open Meta-Agents) is a meta-agent framework designed for building hierarchical, high-performance multi-agent systems. It uses recursive hierarchical structures to solve complex problems by breaking tasks into parallelizable components.

    Key features include:

    • Parallel problem solving: Agents work simultaneously on different parts of complex tasks.
    • Transparent development: Clear structure for easy debugging and context-engineering.
    • Extensibility: Open-source platform designed for community-driven customization.
  3. Understand ROMA Core Concepts and Glossary

    main

    ROMA is built on several key concepts for hierarchical task execution and agentic reasoning:

    Core Concepts

    • DSPy: The underlying declarative framework for prompting and tool integration.
    • Prediction Strategy: The specific DSPy class or function used for reasoning (e.g., CoT, ReAct).
    • SubTask: A Pydantic model representing a unit of work, containing a goal, task_type, and dependencies.
    • NodeType: Indicates if the Atomizer chose to PLAN or EXECUTE.
    • TaskType: A MECE classification for subtasks, including RETRIEVE, WRITE, THINK, CODE_INTERPRET, and IMAGE_GENERATION.
    • Context Defaults: Keyword arguments passed to dspy.context(...) during calls.

    Configuration & Storage

    • FileStorage: Provides isolated directories per task execution using an Execution ID.
    • DataStorage: An automatic Parquet storage system for large toolkit responses based on a size threshold.
    • Base Path: The root directory for storage (supports local paths or S3 buckets).
    • Profile: A named configuration preset (e.g., general, crypto_agent).
    • Configuration Override: Runtime values that supersede profile or default settings.

    Toolkits

    • BaseToolkit: The abstract base class for all toolkits, handling storage integration and tool registration.
    • REQUIRES_FILE_STORAGE: A metadata flag for toolkits that depend on FileStorage (e.g., FileToolkit).
    • Tool Selection: Mechanisms to include or exclude specific tools from a toolkit.
    • Storage Threshold: The size limit (in KB) that triggers Parquet format storage for responses.
  4. Understand the ROMA-DSPy Configuration Resolution Order

    main

    ROMA-DSPy uses a layered configuration system where later layers override earlier ones. The resolution order is as follows:

    1. Pydantic Defaults: Base defaults from schema classes.
    2. YAML Config: Explicit configuration file.
    3. Profile: Profile overlay (if specified).
    4. CLI/Runtime Overrides: Command-line arguments.
    5. Environment Variables: Variables prefixed with ROMA__.
    6. Validation: Final validation via Pydantic.
  5. Integrate with MLflow for experiment tracking

    main

    The CLI uses dspy.autolog() to automatically track optimization parameters, metrics, datasets, traces, and intermediate program versions.

    Setup and Usage

    1. Start MLflow server: mlflow server --backend-store-uri sqlite:///mlflow.db --host 0.0.0.0 --port 5000
    2. Run experiment: The CLI handles logging automatically when use_mlflow: true is in the config.
    3. View results: Access the UI at http://localhost:5000.

    If the server is not running, you can verify connectivity with curl http://localhost:5000.

  6. Set up Local S3 Storage via goofys

    main

    Run the local setup script to mount your S3 bucket to the local filesystem using goofys. This ensures the host system can write files that the E2B sandbox can subsequently read.

    chmod +x scripts/setup_local.sh
    ./scripts/setup_local.sh
  7. Understand the ROMA recursive plan–execute loop

    main

    ROMA processes tasks through a recursive loop involving four main stages:

    1. Atomizer: Determines if a request is atomic (directly executable) or requires planning.
    2. Planner: If planning is required, the task is decomposed into smaller subtasks. These subtasks are fed back into the Atomizer, creating a recursive process.
    3. Executors: Handle atomic tasks. Executors can be LLMs, APIs, or other agents, provided they implement an agent.execute() interface.
    4. Aggregator: Collects and integrates results from subtasks to produce the final answer to the original parent task.

    Information Flow:

    • Top-down: Tasks are decomposed into subtasks recursively.
    • Bottom-up: Subtask results are aggregated upwards into solutions for parent tasks.
    • Left-to-right: Subtasks that depend on previous outputs wait for those tasks to complete before execution.
    def solve(task):
        if is_atomic(task):                 # Step 1: Atomizer
            return execute(task)            # Step 2: Executor
        else:
            subtasks = plan(task)           # Step 2: Planner
            results = []
            for subtask in subtasks:
                results.append(solve(subtask))  # Recursive call
            return aggregate(results)       # Step 3: Aggregator
    
    # Entry point:
    answer = solve(initial_request)
  8. Add optional Python dependencies to minimal install

    main

    If using the minimal installation but needing specific feature support, you can install extra dependencies using uv pip install:

    • roma-dspy[api]: REST API dependencies
    • roma-dspy[persistence]: PostgreSQL client dependencies
    • roma-dspy[observability]: MLflow client dependencies
    • roma-dspy[e2b]: E2B code execution
    • roma-dspy[tui]: TUI visualization
    • roma-dspy[dev]: Development tools
    • roma-dspy[all]: All Python dependencies

    Note: Installing extras only adds Python dependencies. Services like PostgreSQL or the API server still require Docker.

    uv pip install roma-dspy[all]
  9. Configure Storage Backends

    main

    Set up persistent storage for execution data and tool results. You can use the local filesystem, S3 (via goofys), or PostgreSQL.

    PostgreSQL Setup: Enable via POSTGRES_ENABLED and provide a DATABASE_URL. You can start PostgreSQL automatically using the just docker-up command.

    Tool Result Storage: To reduce context size and handle large datasets, configure toolkits (like MCPToolkit) to store results larger than a specific threshold in Parquet format.

    storage:
      base_path: ${oc.env:STORAGE_BASE_PATH,/opt/sentient}
      max_file_size: 104857600  # 100MB
    
      # PostgreSQL (execution tracking)
      postgres:
        enabled: ${oc.env:POSTGRES_ENABLED,true}
        connection_url: ${oc.env:DATABASE_URL,postgresql+asyncpg://localhost/roma_dspy}
        pool_size: 10
        max_overflow: 20
    toolkits:
      - class_name: MCPToolkit
        toolkit_config:
          use_storage: true
          storage_threshold_kb: 10  # Store results > 10KB
  10. Production Setup with Docker

    main

    For production environments requiring persistence (PostgreSQL), observability (MLflow), and an API server (FastAPI), use the Docker-based setup. This requires Docker, Docker Compose, and optionally the just command runner.

    Setup Commands

    Use just to automate the build and service startup:

    # Interactive setup (prompts for E2B, S3, etc.)
    just setup
    
    # Or with a specific profile
    just setup crypto_agent
    
    # Manual Docker start options
    just docker-up       # Basic (PostgreSQL + MinIO + API)
    just docker-up-full  # With MLflow observability

    Available Services

    • REST API: http://localhost:8000/docs (FastAPI with interactive docs)
    • PostgreSQL: Automatic persistence for execution history and checkpoints
    • MinIO: S3-compatible storage at http://localhost:9001
    • MLflow: Experiment tracking at http://localhost:5000 (requires docker-up-full)
    # One-command setup (builds Docker, starts services)
    just setup
    
    # Or with specific profile
    just setup crypto_agent
    
    # Verify services running
    curl http://localhost:8000/health
    
    # Solve tasks via API
    just solve "What is the capital of France?"
  11. Best Practices for E2B Integration

    main

    When using E2B with ROMA, follow these best practices to ensure isolation, cost control, and reliability:

    • Isolation: Always scope storage to execution IDs to prevent data leakage between runs.
    • Cleanup: Manually clean up temporary files after an execution to manage storage costs.
    • Cost Monitoring: Regularly track AWS S3 storage usage and E2B sandbox consumption.
    • Versioning: Use versioned E2B templates in production environments to ensure reproducibility.
    • Error Handling: Always validate the success of E2B execution results before processing data.
  12. Run ROMA-DSPy using example configurations

    main
    ROMA-DSPy provides several pre-configured YAML examples in the config/examples/ directory to demonstrate different capabilities like toolkits, MCP servers, and domain-specific agents. You can run these using the just solve command with the -c flag.