Skip to content

feat(llm): carry the cache-write TTL split (5m/1h) into telemetry attributes - #2

Merged
danielzarioiu merged 1 commit into
synapse/v1.6.0-compat1from
feat/cache-write-ttl-split
Oct 10, 2026
Merged

danielzarioiu merged 1 commit into
synapse/v1.6.0-compat1from
feat/cache-write-ttl-split

Conversation

@danielzarioiu

Copy link
Copy Markdown
Member

Producer half of the TTL-exact cache-write metering contract for Synapse Provider Pricing Governance V1. Consumer: namirialgroup/synapse-runtime#39 (accounting-tap cache_write_5m_tokens / cache_write_1h_tokens), which reads exactly these attribute names:

  • gen_ai.usage.cache_creation.input_tokens.5m
  • gen_ai.usage.cache_creation.input_tokens.1h

Bedrock Converse (the Synapse Bedrock leg): parses TokenUsage.cacheDetails[] (AWS CacheDetail {ttl: 5m|1h, inputTokens}) — buffered via ProviderUsage and all three ConverseStream metadata paths. Aggregate-only responses leave the split None; unknown TTL classes count under neither canonical class.

Anthropic native: reads usage.cache_creation.ephemeral_5m/1h_input_tokens from the pass-through rest JSON (Usage::cache_ttl_split) so the client-facing wire stays byte-identical — no typed re-parse, no key reordering (the golden passthrough snapshot changes only in its telemetry stanza). Split overlays via overlay_upstream_usage like every other native usage dimension.

Telemetry: attributes emitted only when the provider reported the split — absent = unknown, never zero; the accounting consumer fails closed (cache_write_ttl_ambiguous) on ambiguous aggregates rather than approximating. Client protocol semantics unchanged: no client-facing struct or translation modified.

Tests: Bedrock cacheDetails parse (5m-only / 1h-only / mixed / aggregate-only), per-class mapping with unknown-class isolation, buffered Converse → LLMResponse end-to-end, Anthropic-native split extraction + aggregate-only fallback, span-attribute emission (split present / aggregate-only absent). agent-llm 423/423, agentgateway 2229/2229; fmt + clippy clean.

Note for reviewers: cross-linked Synapse delivery = namirial-synapse feat/provider-pricing-governance-v1 (Bitbucket PR) + namirialgroup/synapse-infra PR agentgateway#263 (CronJob ownership).

…ributes

Producer half of the TTL-exact cache-write metering contract (consumer:
synapse-runtime accounting-tap PR agentgateway#39, fields cache_write_5m/1h_tokens).

Bedrock Converse: parse TokenUsage.cacheDetails[] (AWS CacheDetail
{ttl: 5m|1h, inputTokens}) — buffered responses via ProviderUsage and all
three ConverseStream metadata paths — into LLMResponse
cache_creation_5m/1h_input_tokens. Aggregate-only responses (older
models) leave the split None; unknown TTL classes count under neither
canonical class.

Anthropic native: read usage.cache_creation.ephemeral_5m/1h_input_tokens
from the pass-through rest JSON (Usage::cache_ttl_split) so the
client-facing wire stays byte-identical — no re-parsed typed field, no
key reordering (golden passthrough snapshot unchanged except the
telemetry stanza). Split overlays via overlay_upstream_usage like every
other native usage dimension.

Telemetry: new span attributes
gen_ai.usage.cache_creation.input_tokens.5m / .1h, emitted only when the
provider reported the split — absent means unknown, never zero, and the
accounting consumer fails closed on ambiguous aggregates rather than
approximating. Client protocol semantics unchanged: no client-facing
struct or translation was modified.

Tests: Bedrock cacheDetails parse (5m-only/1h-only/mixed/aggregate-only),
per-class mapping with unknown-class isolation, buffered Converse →
LLMResponse end-to-end, Anthropic-native split extraction + aggregate-only
fallback, span-attribute emission (split present / aggregate-only absent).
agent-llm 423/423, agentgateway 2229/2229; fmt + clippy clean.
@danielzarioiu
danielzarioiu merged commit abee57f into synapse/v1.6.0-compat1 Oct 10, 2026
4 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant