Skip to content

Contributing to AirsDSP

Thank you for your interest in contributing to AirsDSP! This guide will help you get started.

Code of Conduct

By participating in this project, you agree to maintain a respectful and inclusive environment for all contributors.

Ways to Contribute

Reporting Issues

Found a bug or have a feature request?

  1. Check existing issues first
  2. Create a new issue with:
  3. Clear description of the problem or feature
  4. Steps to reproduce (for bugs)
  5. Expected vs actual behavior
  6. Environment details (OS, Rust version)
  7. Relevant phase (Phase 1, 2, or 3)

Documentation

Improvements to documentation are always welcome:

  • Fix typos or clarify explanations
  • Add code examples
  • Improve API documentation (rustdoc)
  • Write tutorials or guides
  • Update architecture documentation

Code Contributions

Ready to contribute code? Follow these steps:

  1. Fork and Clone

    git clone https://github.com/YOUR_USERNAME/airsdsp
    cd airsdsp
    

  2. Create a Branch

    git checkout -b feature/your-feature-name
    

  3. Make Changes

  4. Follow code standards (see below)
  5. Add tests for new functionality
  6. Update documentation as needed
  7. Ensure changes align with current phase

  8. Run Tests

    # Test specific crate
    cd infra && cargo test
    cd core && cargo test
    
    # Test entire workspace
    cargo test --workspace
    
    # Check for warnings
    cargo clippy --workspace -- -D warnings
    
    # Format code
    cargo fmt --all
    

  9. Commit Changes

    git commit -m "feat(core): add new stage implementation"
    

Follow Conventional Commits

  1. Push and Create PR
    git push origin feature/your-feature-name
    

Then create a pull request on GitHub


Development Setup

Prerequisites

  • Rust 1.75 or later
  • Git
  • API keys for testing (optional, for integration tests)

Clone and Build

git clone https://github.com/airsstack/airsdsp
cd airsdsp

# Build entire workspace
cargo build --workspace

# Build specific crate
cargo build -p airsdsp-infra
cargo build -p airsdsp-core

Run Tests

# Run all tests
cargo test --workspace

# Run tests for specific crate
cargo test -p airsdsp-core

# Run specific test
cargo test -p airsdsp-core test_pipeline_builder

# Run with output
cargo test -- --nocapture

Run Examples

# Set up environment (if needed for integration tests)
export OPENAI_API_KEY="your-key"
export QDRANT_URL="http://localhost:6333"

# Run example
cargo run --example simple_qa

Project Structure

Workspace Layout

airsdsp/
β”œβ”€β”€ Cargo.toml                  # Workspace manifest
β”œβ”€β”€ README.md                   # Workspace overview
β”œβ”€β”€ LICENSE-MIT
β”œβ”€β”€ LICENSE-APACHE
β”‚
β”œβ”€β”€ infra/                      # Layer 1: Infrastructure traits
β”‚   β”œβ”€β”€ Cargo.toml
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ language_model.rs
β”‚   β”‚   β”œβ”€β”€ vector_store.rs
β”‚   β”‚   └── cache.rs
β”‚   └── README.md
β”‚
β”œβ”€β”€ core/                       # Layer 2A: Core execution engine
β”‚   β”œβ”€β”€ Cargo.toml
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ stage/
β”‚   β”‚   β”‚   β”œβ”€β”€ mod.rs
β”‚   β”‚   β”‚   β”œβ”€β”€ demonstrate.rs
β”‚   β”‚   β”‚   β”œβ”€β”€ search.rs
β”‚   β”‚   β”‚   └── predict.rs
β”‚   β”‚   β”œβ”€β”€ pipeline/
β”‚   β”‚   β”‚   β”œβ”€β”€ mod.rs
β”‚   β”‚   β”‚   β”œβ”€β”€ builder.rs
β”‚   β”‚   β”‚   └── context.rs
β”‚   β”‚   └── hooks/
β”‚   β”‚       β”œβ”€β”€ mod.rs
β”‚   β”‚       β”œβ”€β”€ logging.rs
β”‚   β”‚       └── metrics.rs
β”‚   └── README.md
β”‚
β”œβ”€β”€ patterns/                   # Layer 2B: Pattern library
β”‚   β”œβ”€β”€ Cargo.toml
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ cot.rs
β”‚   β”‚   β”œβ”€β”€ react.rs
β”‚   β”‚   └── multi_hop.rs
β”‚   └── README.md
β”‚
β”œβ”€β”€ eval/                       # Layer 2C: Evaluation metrics
β”‚   β”œβ”€β”€ Cargo.toml
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ g_eval.rs
β”‚   β”‚   └── metrics.rs
β”‚   └── README.md
β”‚
β”œβ”€β”€ debug/                      # Layer 2C: Debugging tools
β”‚   β”œβ”€β”€ Cargo.toml
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ tracing.rs
β”‚   β”‚   └── inspector.rs
β”‚   └── README.md
β”‚
β”œβ”€β”€ orchestration/              # Layer 3: Multi-pipeline orchestration
β”‚   β”œβ”€β”€ Cargo.toml
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs
β”‚   β”‚   β”œβ”€β”€ routing/
β”‚   β”‚   β”œβ”€β”€ classification/
β”‚   β”‚   └── context/
β”‚   └── README.md
β”‚
β”œβ”€β”€ examples/                   # Example applications
β”‚   β”œβ”€β”€ simple_qa/
β”‚   β”œβ”€β”€ math_solver/
β”‚   └── multi_pipeline/
β”‚
└── docs/                       # Workspace documentation
    β”œβ”€β”€ architecture.md
    β”œβ”€β”€ getting-started.md
    └── ...

Crate Dependencies

orchestration β†’ patterns β†’ core β†’ infra
            β†˜           β†—
eval ────────────────────
debug ───────────────────

Code Standards

Rust Style Guide

Follow the official Rust Style Guide and Microsoft Rust Guidelines.

Key points:

  • Use cargo fmt for formatting
  • Use cargo clippy for linting
  • Follow Rust naming conventions (snake_case, PascalCase, etc.)
  • Document public APIs with doc comments
  • Add examples to documentation

Code Organization

// Standard library imports
use std::sync::Arc;
use std::collections::HashMap;

// External crate imports
use tokio::sync::RwLock;
use async_trait::async_trait;
use anyhow::Result;

// Internal workspace crate imports
use airsdsp_infra::LanguageModel;

// Internal crate imports
use crate::pipeline::Pipeline;
use crate::stage::Stage;

Documentation Standards

All public APIs must have documentation following DiΓ‘taxis framework:

/// Creates a new pipeline builder.
///
/// The pipeline builder uses a fluent API to compose stages into a complete
/// DSP pipeline. At least one Predict stage is required.
///
/// # Examples
///
/// ```
/// use airsdsp_core::prelude::*;
///
/// let pipeline = Pipeline::builder()
///     .predict(SimplePredict::new(lm))
///     .build()?;
/// ```
///
/// # Errors
///
/// Returns an error if:
/// - No Predict stage is provided
/// - Stage configuration is invalid
pub fn builder() -> PipelineBuilder {
    PipelineBuilder::new()
}

Error Handling

Use Result and ? operator with descriptive error types:

use thiserror::Error;

#[derive(Debug, Error)]
pub enum StageError {
    #[error("Stage '{0}' execution failed: {1}")]
    ExecutionFailed(String, String),

    #[error("Invalid stage configuration: {0}")]
    InvalidConfig(String),
}

pub async fn execute(&self, ctx: &mut Context) -> Result<(), StageError> {
    let result = self.operation().await
        .map_err(|e| StageError::ExecutionFailed(
            self.name().to_string(),
            e.to_string()
        ))?;
    Ok(result)
}

Testing

Write comprehensive tests:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_stage_name() {
        let stage = MyStage::new();
        assert_eq!(stage.name(), "my_stage");
    }

    #[tokio::test]
    async fn test_pipeline_execution() {
        let mut pipeline = create_test_pipeline();
        let result = pipeline.execute("test").await;
        assert!(result.is_ok());
    }

    #[test]
    fn test_builder_validation() {
        let builder = Pipeline::builder();
        // Should fail - no Predict stage
        assert!(builder.build().is_err());
    }
}

Pull Request Process

Before Submitting

  1. βœ… Tests pass locally (cargo test --workspace)
  2. βœ… Code is formatted (cargo fmt --all)
  3. βœ… No clippy warnings (cargo clippy --workspace -- -D warnings)
  4. βœ… Documentation is updated (rustdoc + markdown)
  5. βœ… Commit messages follow conventional commits
  6. βœ… Changes align with current development phase

PR Description Template

Include in your PR:

## What
Brief description of changes

## Why
Motivation for the changes

## How
Implementation approach

## Testing
How you tested the changes

## Phase
Which phase does this contribute to? (Phase 1, 2, or 3)

## Related Issues
Closes #123

Review Process

  1. Maintainers review your PR
  2. Address feedback and comments
  3. Push updates to your branch
  4. Once approved, PR will be merged
  5. Squash merge to keep clean history

Commit Message Format

Follow Conventional Commits:

<type>(<scope>): <subject>

<body>

<footer>

Types: - feat: New feature - fix: Bug fix - docs: Documentation changes - style: Formatting changes (not code behavior) - refactor: Code refactoring - perf: Performance improvements - test: Test additions or changes - chore: Maintenance tasks - ci: CI/CD changes

Scopes (by crate): - infra: Infrastructure traits - core: Core execution engine - patterns: Pattern library - eval: Evaluation metrics - debug: Debugging tools - orchestration: Multi-pipeline system - workspace: Workspace-level changes

Examples:

feat(core): implement Pipeline builder pattern

Implement fluent API for building pipelines with stages.
Includes validation to ensure at least one Predict stage.

Closes #42
fix(core): handle empty context in Search stage

Add proper error handling when Search stage is called
with empty context.

Fixes #67
docs(workspace): update architecture documentation

Update docs/architecture.md to reflect 6-crate modular structure
based on ADR-001.

Areas Needing Help

Phase 1 (Current - Months 1-3)

High Priority: 1. Infrastructure Traits - Mock implementations for testing - Documentation examples - Integration test helpers

  1. Core Stage Implementations
  2. Basic Demonstrate stages (YAML, JSON)
  3. Basic Search stages (vector, keyword)
  4. Basic Predict stages (simple LLM calls)

  5. Common Hooks

  6. LoggingHook implementation
  7. MetricsHook implementation
  8. CacheHook implementation
  9. ValidationHook implementation

  10. Testing Infrastructure

  11. Test utilities and helpers
  12. Mock implementations
  13. Integration test framework

  14. Documentation

  15. API documentation (rustdoc)
  16. Code examples
  17. Tutorial improvements

Phase 2 (Months 4-6)

Upcoming: 1. Pattern implementations (CoT, ReAct, Multi-hop) 2. Multi-pipeline system 3. Task classification strategies 4. Advanced examples

Phase 3 (Months 7-9)

Future: 1. G-Eval implementation 2. Tracing and debugging tools 3. Observability integrations 4. Performance benchmarking


Getting Help

Need help contributing?

  • GitHub Discussions: Ask questions about development
  • Issues: Tag with question label
  • Documentation: Read Architecture, Roadmap

Testing Guidelines

Unit Tests

Test individual components:

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_component_logic() {
        let component = MyComponent::new();
        assert_eq!(component.value(), expected);
    }
}

Integration Tests

Test crate integration:

// In core/tests/integration_test.rs
use airsdsp_core::*;
use airsdsp_infra::*;

#[tokio::test]
async fn test_full_pipeline() {
    let lm = Arc::new(MockLanguageModel::new());
    let vs = Arc::new(MockVectorStore::new());

    let mut pipeline = Pipeline::builder()
        .search(VectorSearchStage::new(vs))
        .predict(SimplePredict::new(lm))
        .build()
        .unwrap();

    let result = pipeline.execute("test").await;
    assert!(result.is_ok());
}

Property-Based Tests

Use proptest for property testing:

use proptest::prelude::*;

proptest! {
    #[test]
    fn test_pipeline_determinism(input in ".*") {
        let pipeline = create_deterministic_pipeline();
        let result1 = pipeline.execute(&input);
        let result2 = pipeline.execute(&input);
        prop_assert_eq!(result1, result2);
    }
}

Release Process

Releases follow semantic versioning and are handled by maintainers:

  • MAJOR: Breaking changes to public API
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes

Current Status: Pre-1.0 (0.x.x) - Breaking changes may occur in any release - Will stabilize API for 1.0.0 release

Contributors don't need to worry about versioning.


License

By contributing, you agree that your contributions will be licensed under:

  • Apache License 2.0
  • MIT License

You may choose either license.


Recognition

Contributors are recognized in:

  • Release notes
  • CONTRIBUTORS.md file (coming soon)
  • Project README

Development Workflow Tips

Working on Specific Crates

# Build only the crate you're working on
cargo build -p airsdsp-core

# Test only the crate
cargo test -p airsdsp-core

# Watch for changes (requires cargo-watch)
cargo watch -x 'test -p airsdsp-core'

Checking Your Work

# Run all quality checks before submitting PR
cargo fmt --all --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
cargo doc --workspace --no-deps

Debugging Tests

# Run with output
cargo test -- --nocapture

# Run specific test with debug output
RUST_LOG=debug cargo test test_name -- --nocapture

# Run test with backtrace
RUST_BACKTRACE=1 cargo test

Useful Resources

Project Documentation: - Architecture - System design - Overview - High-level introduction - Roadmap - Development phases - Getting Started - API examples

Rust Resources: - Rust Book - Rust API Guidelines - Async Book


Thank you for contributing to AirsDSP!


Ready to contribute? Check out Good First Issues or join our Discussions