From c0193c8cc01c10ebcb763c3db052daa5e7169a91 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:26:51 +0600 Subject: [PATCH 1/9] docs: add CONTRIBUTING.md guide for new contributors --- CONTRIBUTING.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..b34a5ec5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,52 @@ +# Contributing to ROMA + +Thank you for your interest in contributing to ROMA (Recursive Open Meta-Agents)! We welcome contributions from the community to help make this framework better. + +## getting Started + +1. **Fork the repository** on GitHub. +2. **Clone your fork** locally: + ```bash + git clone https://github.com/your-username/ROMA.git + cd ROMA + ``` +3. **Set up your environment**. We recommend using `uv` for fast dependency management: + ```bash + pip install uv + uv pip install -e ".[dev]" + ``` + +## Development Workflow + +1. Create a new branch for your feature or fix: + ```bash + git checkout -b feature/my-new-feature + ``` +2. Make your changes. +3. Run tests to ensure everything is working: + ```bash + pytest + ``` +4. Format your code (if applicable): + ```bash + ruff format . + ``` + +## Pull Request Process + +1. Push your changes to your fork: + ```bash + git push origin feature/my-new-feature + ``` +2. Open a Pull Request against the `main` branch of the upstream repository. +3. Provide a clear description of your changes and why they are necessary. + +## Code of Conduct + +Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. + +## Questions? + +If you have any questions, feel free to open an issue or reach out to the maintainers. + +Happy coding! From 5acb015122ce718bcbcbf57f0b606a710ba4bab1 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:27:33 +0600 Subject: [PATCH 2/9] docs: add Contributing section to README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ff45617a..92e55d09 100644 --- a/README.md +++ b/README.md @@ -784,6 +784,10 @@ executor = Executor( ROMA will ensure both constructor and per-call tools are available to the strategy. +## 🤝 Contributing + +We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on how to get started, set up your development environment, and submit pull requests. + ## 🧪 Testing ```bash From ecc5ddf17ac1f907f2e37ed0598dc1e312073ad0 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:27:51 +0600 Subject: [PATCH 3/9] feat: add get_missing_features utility for easier dependency checks --- src/roma_dspy/utils/lazy_imports.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/roma_dspy/utils/lazy_imports.py b/src/roma_dspy/utils/lazy_imports.py index eadc22ab..32e55e41 100644 --- a/src/roma_dspy/utils/lazy_imports.py +++ b/src/roma_dspy/utils/lazy_imports.py @@ -159,6 +159,31 @@ def get_available_features() -> dict[str, bool]: } +def get_missing_features() -> dict[str, str]: + """ + Get a dictionary of missing optional features and their install commands. + + Returns: + Dictionary mapping missing feature names to their install commands. + """ + features = { + "persistence": ("persistence", HAS_PERSISTENCE), + "observability": ("observability", HAS_MLFLOW), + "s3": ("s3", HAS_S3), + "code_execution": ("e2b", HAS_CODE_EXECUTION), + "api_server": ("api", HAS_API_SERVER), + "tui": ("tui", HAS_TUI), + "wandb": ("wandb", HAS_WANDB), + } + + missing = {} + for feature, (extra, available) in features.items(): + if not available: + missing[feature] = f"uv pip install roma-dspy[{extra}]" + + return missing + + def print_available_features() -> None: """ Print a formatted list of available optional features. From 0a2ed9109a629c881008e7ed16185dc330123a2c Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:28:16 +0600 Subject: [PATCH 4/9] refactor: impove type hints and docstrings in utils --- src/roma_dspy/utils/lazy_imports.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/roma_dspy/utils/lazy_imports.py b/src/roma_dspy/utils/lazy_imports.py index 32e55e41..186ec488 100644 --- a/src/roma_dspy/utils/lazy_imports.py +++ b/src/roma_dspy/utils/lazy_imports.py @@ -20,7 +20,7 @@ def is_available(module_name: str) -> bool: module_name: Name of the module to check (e.g., "sqlalchemy", "mlflow") Returns: - True if module can be imported, False otherwise + bool: True if module can be imported, False otherwise Example: >>> if is_available("mlflow"): @@ -78,7 +78,7 @@ def require_module( raise ImportError(error_msg) -def lazy_import(module_name: str, package: Optional[str] = None): +def lazy_import(module_name: str, package: Optional[str] = None) -> Optional[object]: """ Lazily import a module only when accessed. @@ -90,7 +90,7 @@ def lazy_import(module_name: str, package: Optional[str] = None): package: Package name for relative imports Returns: - Module if available, None otherwise + Optional[object]: The imported module if available, None otherwise Example: >>> mlflow = lazy_import("mlflow") From 9eb9efcc762f3d02f2fe91ec0e65e2a3eb28d13a Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:28:42 +0600 Subject: [PATCH 5/9] test: add unit tests for lazy_imports utility --- tests/unit/test_lazy_imports.py | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/unit/test_lazy_imports.py diff --git a/tests/unit/test_lazy_imports.py b/tests/unit/test_lazy_imports.py new file mode 100644 index 00000000..68fe06dd --- /dev/null +++ b/tests/unit/test_lazy_imports.py @@ -0,0 +1,46 @@ +import sys +from unittest.mock import patch, MagicMock +import pytest +from roma_dspy.utils.lazy_imports import is_available, require_module, get_missing_features, lazy_import + +def test_is_available_existing_module(): + """Test is_available returns True for existing standard library module.""" + assert is_available("os") is True + assert is_available("sys") is True + +def test_is_available_non_existing_module(): + """Test is_available returns False for non-existing module.""" + assert is_available("non_existent_module_xyz_123") is False + +def test_require_module_success(): + """Test require_module does not raise error when module exists.""" + # 'os' should always exist + require_module("os", "OS Feature", "os-extra") + +def test_require_module_failure(): + """Test require_module raises ImportError with helpful message when module missing.""" + with pytest.raises(ImportError) as excinfo: + require_module("non_existent_module_xyz_123", "Cool Feature", "cool-extra") + + error_msg = str(excinfo.value) + assert "Cool Feature requires non_existent_module_xyz_123" in error_msg + assert "uv pip install roma-dspy[cool-extra]" in error_msg + +def test_get_missing_features(): + """Test get_missing_features returns a dict.""" + missing = get_missing_features() + assert isinstance(missing, dict) + # We can't guarantee what's missing in the test environment, but we can check the values structure if any exist + for install_cmd in missing.values(): + assert "uv pip install" in install_cmd + +def test_lazy_import_success(): + """Test lazy_import returns module if it exists.""" + os_mod = lazy_import("os") + assert os_mod is not None + assert os_mod.__name__ == "os" + +def test_lazy_import_failure(): + """Test lazy_import returns None if module does not exist.""" + mod = lazy_import("non_existent_module_xyz_123") + assert mod is None From fc7dcac4da9744088ea7de422fbc09ed5d0fda28 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:29:35 +0600 Subject: [PATCH 6/9] ci: add GitHub Actions workflow for tests --- .github/workflows/test.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..c7debb6d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: Tests + +on: + push: + branches: [ main, dev ] + pull_request: + branches: [ main, dev ] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + run: pip install uv + + - name: Install dependencies + run: uv pip install --system -e ".[dev]" + + - name: Run tests + run: | + pytest tests/unit/test_lazy_imports.py + # We run only the new tests first to ensure our changes are good. + # Ideally, we would run all tests, but existing tests might require more setup (e.g. Docker). From dec309421d90e9276c47cb1ae656aeec253f4e34 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:30:09 +0600 Subject: [PATCH 7/9] chore: add project keywords for better discoverability --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index dcde821e..b069ab57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,7 @@ name = "roma-dspy" version = "0.1.0" description = "Recursive agentic problem solver" readme = "README.md" +keywords = ["agents", "ai", "dspy", "llm", "multi-agent", "framework", "recursive"] authors = [ { name = "salzubi401", email = "salaheddin@sentient.xyz" }, { name = "baran nama", email = "baran@sentient.xyz" } From 14c5806e9e7420e20ad260e8cb900181f9e8c331 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 07:30:51 +0600 Subject: [PATCH 8/9] docs: expand core module documentation --- src/roma_dspy/core/__init__.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/roma_dspy/core/__init__.py b/src/roma_dspy/core/__init__.py index 06d78a65..cc6df9a6 100644 --- a/src/roma_dspy/core/__init__.py +++ b/src/roma_dspy/core/__init__.py @@ -1,4 +1,11 @@ -"""Core runtime components for ROMA-DSPy.""" +""" +Core runtime components for ROMA-DSPy. + +This module exposes the main building blocks of the framework, including: +- Engine components (Solver, DAG) +- Modules (Atomizer, Planner, Executor, Aggregator, Verifier) +- Signatures and Data Structures +""" from .engine import ( TaskDAG, From 18f2866c64a0ae12b2f8e804800433bc76b38ac4 Mon Sep 17 00:00:00 2001 From: Dark-Brain07 Date: Wed, 11 Feb 2026 08:10:15 +0600 Subject: [PATCH 9/9] ci: use minimal filtered dependencies for tests to fix build --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c7debb6d..38fd9f5d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,10 @@ jobs: run: pip install uv - name: Install dependencies - run: uv pip install --system -e ".[dev]" + # Install minimal dependencies to avoid issues with heavy dev tools like python-magic + run: | + uv pip install --system -e . + uv pip install --system pytest pytest-asyncio pytest-mock pytest-loguru - name: Run tests run: |