Provider-aware exact counting: registered by the adopter, never fetched here.
The demand is real — an operator reconciling invoices, or trimming to the last
token of a 200k window, needs the provider's own arithmetic, not four
characters per token. The usual way to serve it is to import a tokenizer
library and let it fetch an encoding on first use, and that turns prompt
assembly into a network operation: the first request after a cold deploy blocks
on a download, and on a container with no egress it fails outright, in the
budget layer, with a stack trace that names a vocabulary file.
So exactness arrives from the outside. An adopter constructs their counter —
with whatever SDK, cache warming, or vendored vocabulary they choose — and
registers it. This package holds the seam and refuses anything that admits it
would download, at registration time, on the machine that wrote the config.
ExactCounterRegistry
The adopter's provider-exact counters, by provider name.
Mutable by design and by construction order: registration happens once, at
assembly time, before any policy is resolved against it. Lookup is
read-only, so a resolved :class:~.values.CounterResolution cannot change
under a running request.
Source code in src/symfonic/services/budget/registry.py
| def __init__(self) -> None:
self._specs: dict[str, ExactCounterSpec] = {}
|
get
get(provider: str) -> ExactCounterSpec | None
The registered spec for provider, or None.
Source code in src/symfonic/services/budget/registry.py
| def get(self, provider: str) -> ExactCounterSpec | None:
"""The registered spec for ``provider``, or ``None``."""
return self._specs.get(_key(provider))
|
providers
providers() -> tuple[str, ...]
Every registered provider, in registration order.
Source code in src/symfonic/services/budget/registry.py
| def providers(self) -> tuple[str, ...]:
"""Every registered provider, in registration order."""
return tuple(spec.provider for spec in self._specs.values())
|
register
register(spec: ExactCounterSpec, *, replace: bool = False) -> None
Accept a counter for spec.provider.
Refuses a spec that does not claim to be offline, and refuses to
silently shadow an existing registration — a second registration for
the same provider is either a bug or an intentional override, and only
the caller knows which, so replace makes them say.
Source code in src/symfonic/services/budget/registry.py
| def register(self, spec: ExactCounterSpec, *, replace: bool = False) -> None:
"""Accept a counter for ``spec.provider``.
Refuses a spec that does not claim to be offline, and refuses to
silently shadow an existing registration — a second registration for
the same provider is either a bug or an intentional override, and only
the caller knows which, so ``replace`` makes them say.
"""
if not spec.offline:
raise ExactCounterUnavailableError(
f"counter for {spec.provider!r} does not declare itself offline. "
"Budgeting must not fetch a tokenizer: warm the vocabulary at "
"build time and register a counter that reads it locally."
)
key = _key(spec.provider)
if key in self._specs and not replace:
raise ExactCounterUnavailableError(
f"a counter for {spec.provider!r} is already registered; pass "
"replace=True to override it deliberately."
)
self._specs[key] = spec
|
resolve_counter
resolve_counter(policy: BudgetPolicy, registry: ExactCounterRegistry | None) -> CounterResolution
Pick the counter policy asked for, or say why it could not be had.
Three modes, three different failure stances, and the differences are the
reason the enum has three members rather than a boolean:
HEURISTIC never consults the registry at all — a policy that asked
for the cheap deterministic counter gets it even where an exact one
exists, because reproducibility was the thing it wanted.
EXACT raises when nothing is registered. Estimating for an operator
who asked for exact arithmetic is wrong in a direction nobody can see.
EXACT_PREFERRED falls back and records the degradation, so the
difference between "precise" and "close enough" survives into the
diagnostics instead of being lost at the call site.
Source code in src/symfonic/services/budget/registry.py
| def resolve_counter(
policy: BudgetPolicy, registry: ExactCounterRegistry | None
) -> CounterResolution:
"""Pick the counter ``policy`` asked for, or say why it could not be had.
Three modes, three different failure stances, and the differences are the
reason the enum has three members rather than a boolean:
* ``HEURISTIC`` never consults the registry at all — a policy that asked
for the cheap deterministic counter gets it even where an exact one
exists, because reproducibility was the thing it wanted.
* ``EXACT`` raises when nothing is registered. Estimating for an operator
who asked for exact arithmetic is wrong in a direction nobody can see.
* ``EXACT_PREFERRED`` falls back **and records the degradation**, so the
difference between "precise" and "close enough" survives into the
diagnostics instead of being lost at the call site.
"""
fallback = HeuristicTokenCounter(chars_per_token=policy.chars_per_token)
if policy.mode is CountingMode.HEURISTIC:
return CounterResolution(counter=fallback, mode=CountingMode.HEURISTIC)
spec = registry.get(policy.provider) if registry is not None else None
if spec is not None:
return CounterResolution(
counter=spec.counter,
mode=CountingMode.EXACT,
provider=spec.provider,
revision=spec.revision,
)
if policy.mode is CountingMode.EXACT:
raise ExactCounterUnavailableError(
f"no exact token counter is registered for provider {policy.provider!r}. "
"Register one with ExactCounterRegistry.register(...), or declare "
"mode=CountingMode.EXACT_PREFERRED to accept the offline estimate."
)
return CounterResolution(
counter=fallback,
mode=CountingMode.HEURISTIC,
provider=policy.provider,
degraded=True,
reason=(
f"no exact counter registered for {policy.provider!r}; budgeting with "
f"the offline estimate at {policy.chars_per_token} chars/token."
),
)
|