symfonic.capabilities.prompting.cache¶
cache ¶
The cache-region model: what a provider caches, and what it may never hold.
A region is one contiguous run of rendered contributions that share a cache annotation. Regions are derived, never declared: a contributor states whether its content is cacheable and at which TTL tier, and the compiler decides where the breakpoints fall. That split is what keeps two capabilities from each claiming a breakpoint and pushing the prompt past the provider's ceiling.
Two invariants are enforced here rather than reviewed:
- A volatile contribution never enters a cached region. A per-turn token inside a cached prefix invalidates that prefix on every turn, which converts a cache into a slower, more expensive uncached prompt.
- The emitted TTL ladder is non-increasing. Anthropic's messages endpoint
rejects an ascending ladder outright (
ttl values must be in descending order); a 5m breakpoint followed by a 1h breakpoint is a 400, not a degraded cache. Promotion, never demotion: lowering a declared tier would silently shorten a cache an operator paid to lengthen.
CacheDirective
dataclass
¶
One contribution's (or region's) cache annotation.
ttl without cacheable is inert by construction rather than by
convention: :meth:marker reads cacheable first, so a directive that
names a tier it never earned cannot leak a marker onto the wire.
marker ¶
The wire-level cache_control value, or None when uncached.
The marker is reconstructed from ttl rather than passed through
from anything a caller built, so the wire shape stays canonical however
the directive was assembled.
Source code in src/symfonic/capabilities/prompting/cache.py
CacheRegion
dataclass
¶
CacheRegion(index: int, layer: Layer, directive: CacheDirective, text: str, contribution_ids: tuple[str, ...], digest: str)
One cache-addressable span of the compiled prompt.
annotation ¶
This region as a provider content block, marker included when cached.
Source code in src/symfonic/capabilities/prompting/cache.py
CacheTtl ¶
Bases: StrEnum
The two TTL tiers a cache breakpoint can advertise.
RegionRow ¶
Bases: NamedTuple
One rendered contribution, as the region planner sees it.
A narrow tuple rather than the full rendered value: the planner must not be able to read a tier, a trust flag, or a source, because any of those would become a second place cache decisions get made.
normalise_ttl_ladder ¶
Promote earlier cached regions to the highest tier appearing to their right.
Right-to-left scan tracking the high-water tier. Uncached regions are skipped — they carry no marker and so do not participate in the provider's ladder — which is why a volatile region between two cached ones does not reset the rule.
Source code in src/symfonic/capabilities/prompting/cache.py
plan_regions ¶
Group rows into regions, breaking wherever the annotation changes.
Rows arrive already ordered by the compiler. Empty rows are skipped rather than emitted: a region whose only content is an empty string still costs a breakpoint, and breakpoints are the scarce resource here.