Provider Router¶
ProviderRouter selects the right model and provider based on role, budget, and compliance — no manual configuration needed.
from meshflow.agents.router import ProviderRouter, auto_provider, auto_model
from meshflow import Agent
# One-liner: auto-select provider for a given role
agent = Agent(name="planner", role="planner", provider=auto_provider("planner"))
# Budget-aware: stay under $0.01/run → picks haiku automatically
agent = Agent(name="batch", role="executor", provider=auto_provider(budget_usd=0.005))
# Compliance-aware: HIPAA/SOX/GDPR → always routes to opus
agent = Agent(name="reviewer", role="critic", provider=auto_provider(compliance="hipaa"))
ProviderRouter¶
from meshflow.agents.router import ProviderRouter
router = ProviderRouter()
# Returns (provider, model_id)
provider, model = router.route("executor", budget_usd=0.003)
provider, model = router.route("planner", compliance="hipaa")
Default Routing Table¶
Routing rules are checked in this order:
| Rule | Condition | Model |
|---|---|---|
| 1. Compliance gate | hipaa, sox, gdpr, pci, nerc |
claude-opus-4-7 |
| 2. Custom override | set_rule() applied for this role |
custom |
| 3. Budget gate | budget_usd < $0.01 |
claude-haiku-4-5-20251001 |
| 4. Role default | see table below | — |
Role defaults:
| Role | Default Model |
|---|---|
orchestrator |
claude-sonnet-4-6 |
planner |
claude-sonnet-4-6 |
critic |
claude-sonnet-4-6 |
researcher |
claude-sonnet-4-6 |
guardian |
claude-opus-4-7 (safety non-negotiable) |
executor |
claude-haiku-4-5-20251001 |
| any other | claude-sonnet-4-6 |
Custom Rules¶
router = ProviderRouter()
router.set_rule("executor", model="claude-haiku-4-5-20251001", budget_ceiling=0.01)
provider, model = router.route("executor", budget_usd=0.003)
Explain a Routing Decision¶
explanation = router.explain("critic", budget_usd=0.05, compliance="")
# "model='claude-sonnet-4-6' (role='critic' default)"
explanation = router.explain("executor", budget_usd=0.002)
# "model='claude-haiku-4-5-20251001' (budget=$0.0020 < $0.01 → haiku)"
route_with_health() — Auto-Fallback on Degraded Models¶
router = ProviderRouter()
router.set_fallback_chain(
"claude-opus-4-7",
"claude-sonnet-4-6",
"claude-haiku-4-5-20251001",
)
# Skips any model whose health score is below the degraded threshold
provider, model = router.route_with_health("planner", budget_usd=0.5)
route_with_health() consults the global ModelHealthTracker. If the primary model is degraded it walks the fallback chain and returns the first healthy model. If all are degraded, it returns the model with the highest health score.
set_fallback_chain()¶
router.set_fallback_chain(
"claude-opus-4-7",
"claude-sonnet-4-6",
"claude-haiku-4-5-20251001",
)
# Returns self — chainable
The primary model is always prepended to the chain even if not listed. Fallback order is preserved.
Convenience Functions¶
auto_provider()¶
from meshflow.agents.router import auto_provider
provider = auto_provider() # executor, $1.00 budget
provider = auto_provider(role="planner")
provider = auto_provider(role="critic", budget_usd=0.005)
provider = auto_provider(compliance="sox")
auto_model()¶
Returns only the model ID string — useful when you want to inspect the selection without constructing a provider.
from meshflow.agents.router import auto_model
model = auto_model("planner") # "claude-sonnet-4-6"
model = auto_model("executor", budget_usd=0.002) # "claude-haiku-4-5-20251001"
model = auto_model("guardian", compliance="hipaa") # "claude-opus-4-7"
Latency-Constrained Routing¶
provider, model = router.route_with_latency(
"executor",
budget_usd=0.5,
max_p95_latency_ms=800.0,
prefer="speed", # or "quality"
)
route_with_latency() filters candidates where health.is_degraded() is True or where p95 latency exceeds max_p95_latency_ms. Among the remaining candidates it picks the fastest (prefer="speed") or the highest health-score model (prefer="quality").