Python SDK

A provider-agnostic control plane.

The SDK chooses models but never owns credentials. Bring any model client; keep authentication, budgets, and observability in your application.

Route only

route.py
from smol_router import Router

  router = Router.from_files("model.json", "router.json")
  result = router.route(
  "Prove this queue is linearizable",
  minimum_tier="medium",
)

print(result.tier.label)
print(result.model)
  print(result.decision.confidence)

Invoke, validate, escalate

If an output fails your task check, execute advances one tier at a time. Retryable provider errors also escalate; non-retryable errors stay visible.

execute.py
from smol_router import ModelTarget, ProviderError

  def invoke(target: ModelTarget, prompt: str) -> str:
    try:
      return client.generate(model=target.model, prompt=prompt)
  except TimeoutError as exc:
    raise ProviderError(str(exc), retryable=True)

result = router.execute(
  prompt,
  invoke,
  validate=answer_passes_tests,
)

print(result.output)
print(result.escalated)

Async providers

execute_async mirrors the synchronous contract and accepts either synchronous or asynchronous validators.

async.py
result = await router.execute_async(
  prompt,
  invoke=async_provider_call,
  validate=async_task_check,
)

Stable outputs

  • RoutingResult resolves tier, model, provider, confidence, probabilities, expected costs, and decision reason.
  • ExecutionResult adds provider output and every attempted tier.
  • Configuration and returned model metadata are immutable.
  • Domain errors derive from RouterError.