Skip to main content

Smart LLM model router - auto-starts proviz-server binary, no Docker required

Project description

ProvizElekto

Smart LLM model router. Picks the best model for each call based on context size, rate limits, and capabilities — and retries automatically on failure.

Your app → pz.call(step, fn)               → CallResult
           pz.call_litellm(step, messages) → CallResult
                    ↕  (automatic)
           select → LLM call → report → retry on failure
                    ↕
              proviz-server (Rust)
          rate-limit state · catalog

Key difference from LiteLLM fallback: LiteLLM retries after failure. ProvizElekto picks the right model before the call — skipping models that are rate-limited or near their quota, can't fit the context, or lack required capabilities — then retries with the next eligible model automatically.

Features

  • Context-aware selection - don't waste a 128k model on a 1k prompt
  • Proactive quota tracking - sliding-window counters (RPM/TPM/RPD/TPD) plus atomic in-flight reservations; avoids over-booking before any 429 fires
  • Provider-anchored windows - every successful call forwards x-ratelimit-remaining-* headers back to the server; the window floor is clamped to provider reality so internal estimates can't drift below what the provider actually sees
  • Scored selection - picks the best model across all eligible candidates: headroom (50%), quality (25%), cost (15%), latency (10%)
  • Capability filtering - hard requirements for function calling, JSON mode
  • Quality floor - reject models below a quality threshold per step
  • Model groups - define named pools of models (e.g. "fast-chat", "coding-tier1") and restrict selection to that pool
  • Your keys, your models - curated catalog, no vendor proxy
  • Zero-infra - pip install proviz-elekto auto-starts the Rust server as a subprocess
  • Any language - HTTP API, not a library binding
  • Pluggable storage - SQLite (default) or PostgreSQL

Installation

ProvizElekto consists of a Rust server and various clients.

pip install proviz-elekto          # core only
pip install proviz-elekto[litellm] # + built-in LiteLLM integration

The proviz-server binary is bundled in the wheel.

CLI tool (proviz) is also included:

proviz --help

Documentation

Quickstart

With LiteLLM (recommended)

from proviz_elekto import ProvizElekto

pz = ProvizElekto(db_path="./proviz.db")
# or PostgreSQL: pz = ProvizElekto(database_url=os.environ["DATABASE_URL"])

result = pz.call_litellm(
    step="verdict",
    messages=[{"role": "user", "content": "Summarize this document..."}],
    estimated_tokens=2500,
    requires_json_mode=True,
)
print(result.provider, result.candidate.model_slug, result.total_tokens)
# → mistral mistral-small-latest 312

call_litellm() selects the best available model, calls it, reports the outcome, and retries with the next eligible model on any failure — automatically.

With a custom LLM caller

import anthropic

client = anthropic.Anthropic()

def my_llm(candidate):
    return client.messages.create(
        model=candidate.model_slug,
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello"}],
    )

result = pz.call("verdict", my_llm, estimated_tokens=100)
print(result.candidate.brand_slug, result.prompt_tokens)

Pass any callable that accepts a ModelCandidate and returns a response. ProvizElekto wraps it with the same select → report → retry loop.

Low-level API

If you need direct control over selection and reporting:

candidate = pz.select(step="verdict", estimated_tokens=2500)
try:
    response = my_llm_call(candidate)

    # Read provider rate-limit headers (Mistral/OpenAI style; Anthropic style also supported)
    hdrs = getattr(response, "_hidden_params", {}).get("additional_headers") or {}
    rem_req = hdrs.get("x-ratelimit-remaining-requests")
    rem_tok = hdrs.get("x-ratelimit-remaining-tokens")

    pz.report_success(
        candidate.model_id,
        estimated_tokens=candidate.estimated_tokens,  # releases in-flight reservation
        actual_tokens=response.usage.total_tokens,    # improves TPM window accuracy
        remaining_requests=int(rem_req) if rem_req is not None else None,
        remaining_tokens=int(rem_tok)   if rem_tok is not None else None,
    )
    # report_success is fire-and-forget — returns immediately, HTTP call runs in background
except RateLimitError as exc:
    msg = str(exc).lower()
    if "day" in msg or "daily" in msg:
        error_type = "tpd"
    elif "token" in msg:
        error_type = "tpm"
    else:
        error_type = "rpm"
    pz.report_rate_limit(candidate.model_id, error_type)  # synchronous — must complete before retry
except Exception:
    pz.report_error(candidate.model_id, "other")

estimated_tokens in each report call releases the in-flight reservation made at selection time. Omitting it is safe (legacy clients work unchanged) but leaves the in-flight counter inflated until the next selection clears it.

report_success is non-blocking: the HTTP call to proviz runs in a background daemon thread so the caller receives the LLM result without waiting for the round-trip. report_rate_limit and report_error remain synchronous because the model must be blocked in proviz before the retry select() call.

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

proviz_elekto-0.4.8-py3-none-win_amd64.whl (2.8 MB view details)

Uploaded Python 3Windows x86-64

proviz_elekto-0.4.8-py3-none-musllinux_1_2_x86_64.whl (3.4 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

proviz_elekto-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

proviz_elekto-0.4.8-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (6.1 MB view details)

Uploaded Python 3macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file proviz_elekto-0.4.8-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for proviz_elekto-0.4.8-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 f534520b3d9a191e868e16b6c457156a3200d3ba2809250b3b89fe9f03082aa5
MD5 0f5e23611ea5f9760ef035ef66be2e3f
BLAKE2b-256 ccbce381691a4ea6e9f9e5cbebd70c4a31d675607db3a3293b3224b49422477b

See more details on using hashes here.

Provenance

The following attestation bundles were made for proviz_elekto-0.4.8-py3-none-win_amd64.whl:

Publisher: release.yml on JustGui/proviz-elekto

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proviz_elekto-0.4.8-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for proviz_elekto-0.4.8-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 846e473f4cc97ce20f3a46af70000a8e8a6506c822acd967bda89e26fdeb9e83
MD5 44dc17681822b4c6625b08935bd7af26
BLAKE2b-256 cf37319603fb5cc1ba404d3a539df8d25cceb42e77edb34c55f9f24bf74f8aa1

See more details on using hashes here.

Provenance

The following attestation bundles were made for proviz_elekto-0.4.8-py3-none-musllinux_1_2_x86_64.whl:

Publisher: release.yml on JustGui/proviz-elekto

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proviz_elekto-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for proviz_elekto-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 337b829b44b16708886c1d7754d306690e453ef61fe8846073e75a1e1f484fd2
MD5 fee04fc7dbfe5542f2cca8d6d7e2ced6
BLAKE2b-256 09a41f60cd370a76d192103455262e5d5afd6c6df89be520508c508d8fa2047a

See more details on using hashes here.

Provenance

The following attestation bundles were made for proviz_elekto-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on JustGui/proviz-elekto

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file proviz_elekto-0.4.8-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for proviz_elekto-0.4.8-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 09aeb030866da8ecab71d8bd2053fb892d920a6f8195f1ff1f35d0431c863368
MD5 213fde068aeee31c5a31d1546bbe0d72
BLAKE2b-256 d898904749f82a68b07e95e0887b24ed59b97adf416996f8340cbde2164fc26a

See more details on using hashes here.

Provenance

The following attestation bundles were made for proviz_elekto-0.4.8-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on JustGui/proviz-elekto

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page