Skip to content

Invocation Controls

Install

Terminal window
pip install "briefcase-ai[controls]==4.4.0"

Gate a call

import asyncio
from briefcase.controls import FixedWindowQuotaStore, Gateway, GatewayConfig
gateway = Gateway(GatewayConfig(
quota_store=FixedWindowQuotaStore(),
buckets={"suggestions": {"limit": 10, "window_s": 60}},
))
outcome = asyncio.run(gateway.invoke(
tenant_id="tenant-1",
bucket="suggestions",
fn=lambda: "approved response",
))
print(outcome.ok, outcome.value, outcome.tokens_remaining)

The gateway checks entitlements first, acquires quota second, then calls the provider. It returns a typed outcome with ok, a value on success, or one of hard_capped, quota_exhausted, throttled, and internal on failure. Cancellation and process-exit exceptions propagate.

Ports and failure policy

Applications own their storage and tenancy rules by implementing QuotaStore, EntitlementsHook, CacheStore, and UsageSink. Port methods may be sync or async. port_error_policy or portErrorPolicy chooses propagate, allow, or deny; the default is propagate.

ProviderRegistry adds preferred-first provider fallback in Python. A scoped_credential() is bound to exactly one provider, so a tenant key never falls through to another provider’s platform credentials.

Retry and throttle classification

classify_provider_error and classifyProviderError treat HTTP 429 as a throttle. HTTP 503 and AWS ServiceQuotaExceededException are transient but do not open a cooldown. Message-text matching is opt-in. The retry helpers use capped exponential backoff, jitter, and a deadline guard.

Limits

  • The bundled quota stores are in-process. Use a shared QuotaStore for a multi-process or distributed ceiling.
  • Concrete model clients and persistent ports stay application-side.
  • A synchronous Python fn cannot be interrupted by deadline_s; only an awaitable is bounded.

API reference

briefcase.controls and the TypeScript controls API have the full gateway, quota-port, retry-classification, and pipeline signatures.

Where this fits

Controls open the Control & Route act: decide whether a call runs at all, then decide where the work goes.