A Python-first Agentic AI Framework — provider-agnostic, async-first, middleware-driven
Project description
Flux
A Python-first Agentic AI Framework
Provider-agnostic · Async-first · Middleware-driven · Zero core dependencies
Quick Start
import asyncio
from flux import Agent, Runner
# 3 lines to get started
agent = Agent(name="assistant", instructions="You are helpful")
result = asyncio.run(Runner.run(agent, "Hello!"))
print(result.final_output)
Features
- Provider Agnostic — Ollama, OpenAI, Anthropic, Groq, DeepSeek, OpenRouter
- Async First — Non-blocking by default, sync wrappers available
- Protocol Based — Structural typing, no inheritance required
- Middleware — Composable middleware stack (logging, caching, retry, rate-limiting)
- Event Driven — Decoupled event bus for observability
- Tools —
@tooldecorator, tool registry, built-in tools - Handoffs — Agent-to-agent routing
- Guardrails — Input/output validation
- Sessions — Conversation persistence (in-memory, SQLite)
- Memory — Short-term and long-term memory
- Streaming — Real-time token streaming
- Tracing — Console and file-based tracing
Installation
# Core framework (zero dependencies)
pip install flux-agents
# With providers
pip install flux-agents[ollama] # Ollama
pip install flux-agents[openai] # OpenAI
pip install flux-agents[anthropic] # Anthropic
pip install flux-agents[full] # All providers
Usage
Basic Agent
from flux import Agent, Runner
agent = Agent(
name="assistant",
instructions="You are a helpful assistant",
model="ollama/llama3.2",
)
result = Runner.run_sync(agent, "What is the capital of France?")
print(result.final_output)
With Tools
from flux import Agent, Runner, tool
@tool
def get_weather(city: str) -> str:
"""Get weather for a city."""
return f"Sunny in {city}"
agent = Agent(
name="weather_bot",
instructions="You help with weather queries",
tools=[get_weather],
)
result = Runner.run_sync(agent, "What's the weather in NYC?")
print(result.final_output)
With Handoffs
from flux import Agent, Runner
router = Agent(
name="router",
instructions="Route to the right specialist",
handoffs=[
Agent(name="coder", instructions="You write code"),
Agent(name="writer", instructions="You write content"),
],
)
result = Runner.run_sync(router, "Write a Python function to sort a list")
print(result.final_output)
Streaming
import asyncio
from flux import Agent, Runner
async def main():
agent = Agent(name="assistant", instructions="You are helpful")
stream = await Runner.run_streamed(agent, "Tell me a story")
async for event in stream:
if hasattr(event, "delta"):
print(event.delta, end="", flush=True)
asyncio.run(main())
With Guardrails
from flux import Agent, Runner, LengthGuardrail, PIIGuardrail
agent = Agent(
name="safe_assistant",
instructions="You are helpful",
guardrails=[
LengthGuardrail(max_chars=5000),
PIIGuardrail(),
],
)
With Middleware
from flux import Agent, Runner, LoggingMiddleware, RetryMiddleware
# Middleware wraps every request
runner = Runner(middlewares=[
LoggingMiddleware(),
RetryMiddleware(max_retries=3),
])
With Sessions
from flux import Agent, Runner, InMemorySession
session = InMemorySession()
agent = Agent(name="assistant", instructions="You remember our conversation")
# First turn
result1 = Runner.run_sync(agent, "My name is Alice", session=session)
# Second turn — agent remembers context
result2 = Runner.run_sync(agent, "What's my name?", session=session)
print(result2.final_output) # "Your name is Alice"
Custom Model
from flux import Agent, Runner
from flux.models.ollama import OllamaModel
model = OllamaModel(model="llama3.2", base_url="http://localhost:11434")
agent = Agent(name="local", instructions="You run locally", model=model)
result = Runner.run_sync(agent, "Hello!")
Custom Provider
from flux.models.base import Model, ModelRequest, ModelResponse
class MyCustomModel:
async def complete(self, request: ModelRequest) -> ModelResponse:
# Your custom implementation
return ModelResponse(content="Hello from custom model!")
async def stream(self, request: ModelRequest):
yield # Your streaming implementation
agent = Agent(name="custom", instructions="Custom model", model=MyCustomModel())
Architecture
flux/
├── agent.py # Agent (immutable dataclass)
├── runner.py # Runner (execution engine)
├── context.py # RunContext, ToolContext
├── config.py # Global configuration
├── exceptions.py # Exception hierarchy
├── models/ # LLM providers (Ollama, OpenAI, Anthropic)
├── tools/ # Tool protocol, @tool decorator, registry
├── handoffs/ # Agent-to-agent routing
├── guardrails/ # Input/output validation
├── sessions/ # Conversation persistence
├── memory/ # Long-term memory
├── streaming/ # Stream event types
├── middleware/ # Composable middleware
├── events/ # Event bus
├── tracing/ # Observability
└── utils/ # JSON schema, tokens, pretty print
Design Principles
- Protocol over ABC — Structural typing, no inheritance required
- Async first — Non-blocking by default
- Zero core deps — Base framework needs no third-party packages
- Middleware over hooks — Composable, testable, standard pattern
- Immutable agents — Thread-safe, cloneable
- Event-driven — Decoupled observability
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
flux_agents-0.1.3.tar.gz
(44.0 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file flux_agents-0.1.3.tar.gz.
File metadata
- Download URL: flux_agents-0.1.3.tar.gz
- Upload date:
- Size: 44.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01e04fe374eafd66d1b91cfa62de15718078dc9e8a4f2215d04e4f80440c46b8
|
|
| MD5 |
98ab48dc885ea4ca7da088b7fa46c82b
|
|
| BLAKE2b-256 |
d9fd6aaeb2c852eb4564c9c175f2bf43687313964785d70253a0eca7457d6d5e
|
File details
Details for the file flux_agents-0.1.3-py3-none-any.whl.
File metadata
- Download URL: flux_agents-0.1.3-py3-none-any.whl
- Upload date:
- Size: 44.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8c3bf34b5e350d14b8d6672b04cd33ceb2465f706d05107613bc0315e189bd9
|
|
| MD5 |
07bbc2b30fcadd094a8bffa9640fe6db
|
|
| BLAKE2b-256 |
85c2398e699ab4f4ae87e8955fb5384b9bb3924fe4ab78e7e887ed8e87835977
|