litellm-dynamo
Meter and enforce budgets on every model call through your LiteLLM proxy — without adding a network hop to the request path. You operate the gateway; Dynamo Protocol gives each caller a capped, revocable allowance; this plugin makes your proxy honor it: no live credential, no completion (HTTP 402).
Payments are none of the plugin's business: the credential might be backed by a no-money control ledger, stablecoin escrow, or a card authorization-backed budget — the plugin neither knows nor cares (mode-agnostic by construction).
Install
pip install "litellm-dynamo[litellm]" # Python ≥ 3.10; LiteLLM pin 1.61.20
Two-minute quickstart
- Point it at your engine host — two env vars are mandatory:
export DYNAMO_ENGINE_URL=http://127.0.0.1:8500 # a running dynamo-core
export DYNAMO_ENGINE_SIGNER=0xYourEngineSigner # PINNED signer; verification is offline
- Choose your token→units mapping (config, not code):
export DYNAMO_UNITS_PER_PROMPT_TOKEN=1
export DYNAMO_UNITS_PER_COMPLETION_TOKEN=2
export DYNAMO_UNITS_PER_REQUEST=0
- Register the hook.
dynamo_hook.pynext to your proxy config:
from litellm_dynamo import DynamoLiteLLMHook, config_from_env
dynamo_hook = DynamoLiteLLMHook(config_from_env())
and in the LiteLLM config:
litellm_settings:
callbacks: dynamo_hook.dynamo_hook
- Run the background loop (sync + async metering — the request path never blocks on the network):
import threading, time
def loop(hook, stream_ids):
while True:
for sid in stream_ids():
try: hook.guard.sync_stream(sid)
except Exception: pass # cache ages toward DENY — fail closed
hook.guard.flush_metering()
time.sleep(10) # keep < DYNAMO_MAX_STALE_SECONDS / 2
threading.Thread(target=loop, args=(dynamo_hook, my_stream_ids), daemon=True).start()
Callers attach their allowance credential per request:
curl http://localhost:4000/v1/chat/completions \
-H "x-dynamo-allowance: <compact-JWS credential>" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'
What it enforces (all fail closed)
| situation | answer |
|---|---|
| no credential / malformed / expired / wrong signer | 402 before ANY upstream cost |
| stream revoked or engine-halted (seen at last sync) | 402 |
| allowance exhausted (local headroom cache) | 402 |
headroom cache stale beyond DYNAMO_MAX_STALE_SECONDS |
402 — never guesses |
| async metering failing | stream halts locally; jobs kept, never dropped |
| upstream call FAILED | never metered — no cost for failed actions |
Verification is offline (JWS against the pinned signer) and metering is async — the request path gains zero network round-trips.
What this does NOT do
- It moves no money. Enforcement and settlement live in the caller's Dynamo deployment; Control Mode credentials are free enforcement — caps and a signed meter, no payments.
- It never reads, stores, or transmits prompt/response content to the
metering side: metering carries
{units, requestRef}and nothing else.
Docs: https://github.com/DynamoProtocol/dynamo-open · License: Apache-2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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 litellm_dynamo-1.0.0.tar.gz.
File metadata
- Download URL: litellm_dynamo-1.0.0.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49b37cc7e63d28ec561bacf2d56a72c41ae4a9a93596c44eccfa6d84b39479a0
|
|
| MD5 |
251e6ce66303161d6a26d0bc0977dd21
|
|
| BLAKE2b-256 |
8170c4169bb89bc2562b1e961a1ab6bec8fdca34fd305d4f2359e1689038871c
|
File details
Details for the file litellm_dynamo-1.0.0-py3-none-any.whl.
File metadata
- Download URL: litellm_dynamo-1.0.0-py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c0380a25cbba10bc2cdbdf7d7dce90fccb99b3c71ed5bcfe1007c1a1d0d4e58
|
|
| MD5 |
218fd106a8ddedbf539f101236785429
|
|
| BLAKE2b-256 |
2e438a111837f04be1ff520b7e0fa9fe90e7409ff8fc5688006f227b2c616854
|