Contributing to dartantic_ai
Your contributions to dartantic_ai are welcome! This guide will help you get started with contributing to the project.
How to Contribute an Issue
If you have found a bug or have a feature request, please open an issue on the GitHub repository.
1. Fork and Clone
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/csells/dartantic_ai.git cd dartantic_ai
2. Set Up Your Development Environment
Before making changes, ensure you can run the existing test suite successfully.
Set Up API Keys for Testing
To run the full test suite, you'll need API keys for various providers. Set these environment variables:
export OPENAI_API_KEY="your-openai-key"
export ANTHROPIC_API_KEY="your-anthropic-key"
export GEMINI_API_KEY="your-google-gemini-key"
export MISTRAL_API_KEY="your-mistral-key"
export COHERE_API_KEY="your-cohere-key"
export OPENROUTER_API_KEY="your-openrouter-key"
export TOGETHER_API_KEY="your-together-key"
Note: Ollama providers run locally and don't require API keys.
3. Run Tests
Verify your setup by running the existing tests:
# Run all tests
dart test
# Run a specific test file
dart test test/chat_models_test.dart
# Run tests with timeout for long-running suites
dart test --timeout=10m
All tests should pass before you make any changes.
4. Make Your Changes
-
Create a new branch for your feature:
git checkout -b feature/your-feature-name
-
Make your changes following the existing code style and patterns
-
Add tests for your new feature - This is critical!
Test Requirements
- Every new feature must have tests
- Follow the testing philosophy in test files (no defensive programming)
- Test both success cases and edge cases
- Ensure your tests work across all applicable providers
Testing Best Practices
- No Exception Hiding: Let exceptions bubble up for diagnosis
- Provider Filtering: Only filter by capabilities (e.g.,
ProviderCaps
) - 80/20 Rule: Test common cases across all providers, edge cases on Google only
- No Duplication: Each functionality should be tested in ONE file only
Example Test Pattern
void runProviderTest(
String description,
Future<void> Function(Provider provider) testFunction, {
Set<ProviderCaps>? requiredCaps,
bool edgeCase = false,
}) {
final providers = edgeCase
? ['google:gemini-2.0-flash'] // Edge cases on Google only
: Providers.all
.where((p) => requiredCaps == null ||
requiredCaps.every((cap) => p.caps.contains(cap)))
.map((p) => '${p.name}:${p.defaultModelNames[ModelKind.chat]}');
for (final providerModel in providers) {
test('$providerModel: $description', () async {
final provider = Providers.get(providerModel.split(':')[0]);
await testFunction(provider);
});
}
}
6. Verify Your Changes
Before submitting:
-
Run all tests and ensure they pass:
dart test
-
Format your code:
dart format .
-
Analyze your code:
dart analyze
7. Submit Your Pull Request
-
Commit your changes with a clear message:
git commit -m "feat: add support for new feature X"
-
Push to your fork:
git push origin feature/your-feature-name
-
Open a Pull Request on GitHub with:
- Clear description of what you've added/changed
- Reference to any related issues
- Confirmation that all tests pass
- Description of the tests you've added
Code Style Guidelines
- Follow Dart conventions and the existing code style
- Use meaningful variable and function names
- Add documentation comments for public APIs
- Keep functions focused and single-purpose
What Makes a Good Contribution?
- Has tests: No PR will be merged without appropriate tests
- Follows patterns: Uses existing patterns and conventions
- Well documented: Includes clear documentation
- Focused: Does one thing well rather than many things poorly
- Compatible: Works across all applicable providers