Copyright 2026 Firefly Software Foundation. Licensed under the Apache License 2.0.
Thank you for considering a contribution. This document explains how to set up your development environment, the coding standards we follow, and the process for submitting changes.
- Python 3.13 or later
- UV for dependency and virtual-environment management
- Git
- Node.js 20+ and npm — only required if you intend to run or modify Firefly Studio from source (the published wheel ships with a pre-built frontend)
git clone https://github.com/fireflyframework/fireflyframework-agentic.git
cd fireflyframework-agentic
uv sync --all-extrasThis installs all runtime and development dependencies, including optional extras for REST, Kafka, RabbitMQ, and Redis.
The Studio frontend is a SvelteKit SPA that lives in studio-frontend/ and is
served by FastAPI from src/fireflyframework_agentic/studio/static/. The published
wheel includes a pre-built bundle, but a fresh git clone does not — running
firefly studio against an unbuilt source tree returns {"detail":"Not Found"}
on every page.
Build the frontend once after cloning (and again after pulling frontend changes):
uv run python scripts/build_studio.pyThe script runs npm install (if needed), npm run build, and copies the output
into the package's static/ directory. After it completes, firefly studio will
serve the UI normally.
uv run pytestTo generate a coverage report:
uv run pytest --cov=fireflyframework_agentic --cov-report=term-missingWe use Ruff for linting and formatting:
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/We use Pyright in standard mode:
uv run pyright src/- Follow PEP 8. Ruff enforces this automatically.
- Maximum line length is 120 characters.
- Use
from __future__ import annotationsat the top of every module. - All public functions, classes, and methods must have docstrings.
- Prefer explicit type annotations over implicit types.
Every Python source file must begin with the Apache 2.0 copyright header:
# Copyright 2026 Firefly Software Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.Imports are organised into three groups, separated by blank lines:
- Standard library
- Third-party packages
- Internal (
fireflyframework_agentic) modules
Ruff isort rules enforce this automatically.
- Every new module must have a corresponding test file in
tests/. - Use
pytestwithpytest-asynciofor asynchronous tests. - Aim for clear, descriptive test names that explain the behaviour under test.
- Mock external services rather than making real network calls.
Use descriptive branch names:
feature/agent-retry-logicfix/prompt-template-escapingdocs/reasoning-patterns-guide
Write clear commit messages in the imperative mood:
Add retry logic to agent lifecycle manager
Introduces configurable retry with exponential backoff when an agent
invocation fails due to a transient provider error.
- Create a feature branch from
main. - Make your changes, ensuring all tests pass and lint is clean.
- Open a pull request against
main. - Fill in the PR template, describing what changed and why.
- Address any review feedback.
- Once approved, the maintainers will merge your PR.
Before opening a PR, confirm that:
- All new code has the copyright header.
- All public APIs have docstrings.
- Tests cover the new or changed behaviour.
uv run ruff check src/ tests/reports no issues.uv run pyright src/reports no errors.uv run pytestpasses.
Open an issue on GitHub with:
- A clear title summarising the problem.
- Steps to reproduce the issue.
- Expected and actual behaviour.
- Your Python version and operating system.
We are committed to providing a welcoming and inclusive experience for everyone. Be respectful, constructive, and professional in all interactions.