Skip to content

symfonic.agent.cutover.budget

budget

Compatibility import for the shared prompt-budget composition binding.

prompt_compile_options

prompt_compile_options(*, context_window: int | None = None, prompt_share: float | None = None, chars_per_token: int | None = None) -> dict[str, Any]

The compile options that bind this deployment's budgeting.

Returned as options for PromptingCapability rather than applied here: the capability owns the compile, and a composition root that pre-compiled for it would be a second compiler.

Source code in src/symfonic/agent/prompt_budget.py
def prompt_compile_options(
    *,
    context_window: int | None = None,
    prompt_share: float | None = None,
    chars_per_token: int | None = None,
) -> dict[str, Any]:
    """The compile options that bind this deployment's budgeting.

    Returned as options for ``PromptingCapability`` rather than applied here:
    the capability owns the compile, and a composition root that pre-compiled
    for it would be a second compiler.
    """
    if context_window is None:
        if prompt_share is not None:
            raise ValueError(
                "prompt_compile_options(prompt_share=...) needs a context_window: "
                "a share is a fraction of a window, and a fraction of an unknown "
                "number is not a ceiling. Declare the model's window, or drop the "
                "share and compile unbounded."
            )
        counter = (
            HeuristicTokenCounter(chars_per_token=chars_per_token)
            if chars_per_token is not None
            else HeuristicTokenCounter()
        )
        return {"estimator": counter}

    service = BudgetService.offline(
        context_window=context_window,
        prompt=prompt_share,
        chars_per_token=chars_per_token,
    )
    options: dict[str, Any] = {"estimator": service.as_token_estimator()}
    limit = service.limit_for(BudgetKind.PROMPT)
    if limit is not None:
        # ``None`` when no share was declared, and that is not a ceiling of
        # zero: an undeclared line is unbudgeted, so the compile stays
        # unbounded and the counter's numbers are a report rather than a gate.
        options["budget"] = PromptBudget(max_total_tokens=limit)
    return options