Development Setup¶
Setting up a development environment for Flux Agents.
Prerequisites¶
- Python 3.11+ (3.12 recommended)
- Git
- Ollama (optional, for local LLM testing)
Installing Python¶
Installing Ollama¶
Ollama is required for running local LLM models during development.
After installing Ollama, pull a model for testing:
Clone and Install¶
# Clone the repository
git clone https://github.com/OWNER/flux-agents.git
cd flux-agents
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # macOS / Linux
# .venv\Scripts\activate # Windows
# Install in development mode with all extras
make dev
# Equivalent to: pip install -e ".[dev,ollama]"
Installation Variants¶
# Minimal (core only, no providers)
pip install -e .
# With Ollama support
pip install -e ".[ollama]"
# With OpenAI support
pip install -e ".[openai]"
# With Anthropic support
pip install -e ".[anthropic]"
# With all providers
pip install -e ".[full]"
# With memory (numpy)
pip install -e ".[memory]"
# Full development install
pip install -e ".[dev,full,memory]"
Running Tests¶
Basic Test Run¶
Test with Coverage¶
# Run tests with coverage report
make test-cov
# Equivalent to: pytest tests/ -v --cov=flux --cov-report=term-missing
Running Specific Tests¶
# Run a specific test file
pytest tests/test_agent.py -v
# Run tests matching a pattern
pytest tests/ -k "test_middleware" -v
# Run with debug output
pytest tests/ -v -s --tb=long
Test Configuration¶
The test configuration is in pyproject.toml:
Tests use asyncio_mode = "auto", so all async def test_* functions are automatically treated as async tests without needing the @pytest.mark.asyncio decorator.
Linting¶
Ruff¶
# Check for lint issues
make lint
# Equivalent to: ruff check flux/ tests/
# Auto-fix issues and format
make format
# Equivalent to:
# ruff format flux/ tests/
# ruff check --fix flux/ tests/
Ruff Configuration¶
From pyproject.toml:
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"]
| Rule Set | Description |
|---|---|
E |
Pycodestyle errors |
F |
Pyflakes |
I |
isort (import sorting) |
UP |
pyupgrade (modernize syntax) |
B |
flake8-bugbear (common bugs) |
SIM |
flake8-simplify (simplification suggestions) |
Type Checking¶
Mypy¶
Mypy Configuration¶
From pyproject.toml:
Strict Mode
Flux uses mypy strict mode. This means all functions must have complete type annotations, and mypy will flag any untyped code. This is by design -- the framework prioritizes type safety.
Makefile Targets¶
All development tasks are available as Makefile targets:
| Target | Command | Description |
|---|---|---|
make install |
pip install -e . |
Install the package in editable mode |
make dev |
pip install -e ".[dev,ollama]" |
Install with dev and Ollama extras |
make test |
pytest tests/ -v |
Run all tests |
make test-cov |
pytest tests/ -v --cov=flux --cov-report=term-missing |
Run tests with coverage |
make lint |
ruff check flux/ tests/ |
Run linter |
make format |
ruff format flux/ tests/ && ruff check --fix flux/ tests/ |
Format and auto-fix |
make typecheck |
mypy flux/ |
Run type checker |
make clean |
Remove caches and build artifacts | Clean the project |
Using Make on Windows¶
If make is not available on Windows, you can run the commands directly:
# Install
pip install -e ".[dev,ollama]"
# Test
pytest tests/ -v
# Lint
ruff check flux/ tests/
# Format
ruff format flux/ tests/
# Type check
mypy flux/
Or install make via Chocolatey: choco install make
Project Structure¶
flux-agents/
├── flux/ # Main package
│ ├── __init__.py # Public API exports
│ ├── agent.py # Agent definition (frozen dataclass)
│ ├── runner.py # Execution engine
│ ├── config.py # Global configuration
│ ├── context.py # RunContext, ToolContext, Usage
│ ├── exceptions.py # Exception hierarchy
│ ├── cli.py # CLI entry point
│ │
│ ├── models/ # LLM provider abstraction
│ │ ├── base.py # Model protocol, Message, ModelRequest/Response
│ │ ├── registry.py # Model registry (name -> provider)
│ │ ├── openai_provider.py # OpenAI implementation
│ │ └── anthropic.py # Anthropic implementation
│ │
│ ├── tools/ # Tool system
│ │ ├── base.py # Tool protocol, ToolResult
│ │ ├── decorator.py # @tool decorator, FunctionTool
│ │ ├── registry.py # ToolRegistry
│ │ ├── schema.py # JSON Schema generation
│ │ └── builtins.py # ShellTool, FileReadTool, FileWriteTool
│ │
│ ├── middleware/ # Middleware pipeline
│ │ ├── base.py # Middleware protocol, RequestContext, Response
│ │ ├── retry.py # RetryMiddleware (exponential backoff)
│ │ ├── rate_limit.py # RateLimitMiddleware (token bucket)
│ │ ├── cache.py # CacheMiddleware (TTL-based)
│ │ └── logging.py # LoggingMiddleware
│ │
│ ├── guardrails/ # Safety guardrails
│ │ ├── base.py # GuardrailResult, InputGuardrail, OutputGuardrail
│ │ └── builtins.py # PIIGuardrail, ProfanityGuardrail, LengthGuardrail
│ │
│ ├── handoffs/ # Agent-to-agent routing
│ │ ├── handoff.py # Handoff, HandoffData
│ │ └── router.py # Handoff lookup utilities
│ │
│ ├── sessions/ # Conversation persistence
│ │ ├── base.py # Session protocol
│ │ ├── in_memory.py # InMemorySession
│ │ └── sqlite.py # SQLiteSession (persistent)
│ │
│ ├── memory/ # Long-term memory
│ │ ├── base.py # Memory protocol, MemoryEntry
│ │ ├── conversation.py # ConversationMemory (wraps Session)
│ │ └── vector.py # VectorMemory (hash-based embeddings)
│ │
│ ├── events/ # Event bus
│ │ └── bus.py # EventBus, Event, event type constants
│ │
│ ├── streaming/ # Streaming support
│ │ └── events.py # StreamEvent types (TextDelta, ToolCall, etc.)
│ │
│ ├── tracing/ # Distributed tracing
│ │ ├── base.py # Span, Tracer protocols, NoopSpan
│ │ ├── console.py # ConsoleTracer (stderr output)
│ │ └── file.py # FileTracer (JSONL output)
│ │
│ └── utils/ # Utilities
│ ├── schema.py # JSON Schema helpers
│ ├── tokens.py # Token counting
│ └── pretty.py # Pretty printing
│
├── tests/ # Test suite
│ ├── conftest.py # Shared fixtures
│ ├── test_agent.py # Agent tests
│ ├── test_models.py # Model protocol tests
│ ├── test_middleware.py # Middleware tests
│ ├── test_guardrails.py # Guardrail tests
│ ├── test_sessions.py # Session tests
│ ├── test_events.py # Event bus tests
│ ├── test_tracing.py # Tracing tests
│ └── test_handoffs.py # Handoff tests
│
├── docs/ # Documentation (MkDocs)
│ ├── deployment/ # Deployment guides
│ └── contributing/ # Contributor guides
│
├── pyproject.toml # Project config, tools config
├── Makefile # Development commands
├── README.md # Project overview
└── LICENSE # MIT License
Key Design Decisions in the Structure¶
- Protocols, not ABCs -- Interfaces like
Model,Tool,Session, andMemoryusetyping.Protocolfor structural subtyping rather than inheritance. - Frozen dataclasses -- Core types like
Agentusefrozen=Truefor immutability. Use.clone()to create modified copies. - Async-first -- All I/O operations (
Runner.run,Tool.execute,Session.get_messages) are async. - Zero core dependencies -- The
fluxpackage itself has no required dependencies. Provider libraries (OpenAI, Anthropic, aiohttp) are optional extras.
IDE Setup¶
VS Code¶
Recommended extensions:
- Python (
ms-python.python) - Pylance (
ms-python.vscode-pylance) - Ruff (
charliermarsh.ruff)
.vscode/settings.json:
{
"python.defaultInterpreterPath": ".venv/bin/python",
"python.analysis.typeCheckingMode": "strict",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
}
}
Common Development Tasks¶
Adding a New Tool¶
- Create the tool class implementing the
Toolprotocol - Add tests in
tests/test_tools.py - Export from
flux/__init__.pyif public
Adding a New Middleware¶
- Create the middleware class implementing the
Middlewareprotocol - Add tests in
tests/test_middleware.py - Export from
flux/__init__.pyif public
Adding a New Guardrail¶
- Subclass
InputGuardrailorOutputGuardrail - Implement the
checkmethod - Add tests in
tests/test_guardrails.py
Adding a New Model Provider¶
- Implement the
Modelprotocol withcompleteandstreammethods - Register in the
ModelRegistry - Add tests in
tests/test_models.py