Skip to content

symfonic.services.budget.values

values

The values a budgeting decision produces.

Every result here is frozen and self-describing. The caller who needs these most is a test asserting that a block was dropped for the right reason, or an operator asking why a memory section vanished from a prompt — neither has a log handler, so the explanation travels as data alongside the answer.

BudgetAllocation dataclass

BudgetAllocation(kind: BudgetKind, limit: int)

One kind's derived ceiling in tokens.

BudgetDiagnostic dataclass

BudgetDiagnostic(kind: str, subject: str, detail: str)

One recorded budgeting decision.

kind is the stage that made it (counting, budget), subject the item or provider it concerns.

BudgetPlan dataclass

BudgetPlan(context_window: int, output_reserve: int, usable: int, allocations: tuple[BudgetAllocation, ...] = (), unallocated: int = 0)

The split of one context window across the kinds that share it.

limit_for

limit_for(kind: BudgetKind) -> int | None

The ceiling for kind, or None when it was never allocated.

None rather than 0: an undeclared kind is unbudgeted, and answering zero would silently truncate every block of a kind the operator simply never mentioned.

Source code in src/symfonic/services/budget/values.py
def limit_for(self, kind: BudgetKind) -> int | None:
    """The ceiling for ``kind``, or ``None`` when it was never allocated.

    ``None`` rather than ``0``: an undeclared kind is unbudgeted, and
    answering zero would silently truncate every block of a kind the
    operator simply never mentioned.
    """
    for allocation in self.allocations:
        if allocation.kind is kind:
            return allocation.limit
    return None

CounterResolution dataclass

CounterResolution(counter: TokenCounter, mode: CountingMode, provider: str = '', revision: str = '', degraded: bool = False, reason: str = '')

Which counter a policy actually got, and whether that was what it asked for.

degraded is never inferred by the caller from mode: an EXACT_PREFERRED policy that fell back and a HEURISTIC policy that got exactly what it wanted both report HEURISTIC, and only one of them is a degradation worth surfacing.

FittedItem dataclass

FittedItem(item_id: str, kind: BudgetKind, text: str, tokens: int, truncated: bool = False, pinned: bool = False)

One item after admission, with what survived of it.

OverflowResult dataclass

OverflowResult(kept: tuple[FittedItem, ...] = (), dropped: tuple[str, ...] = (), limit: int = 0, total_tokens: int = 0, overflowed: bool = False, diagnostics: tuple[BudgetDiagnostic, ...] = ())

The outcome of fitting a sequence of items into one ceiling.

TruncationResult dataclass

TruncationResult(text: str, tokens: int, truncated: bool, dropped_tokens: int = 0)

A string cut to fit, with the arithmetic that explains it.