symfonic.agent.message_usage¶
message_usage ¶
Per-message usage: what the provider reported for one round (CORE-21).
AgentResult.usage is the run's aggregate. This is the per-round figure
that sits on the assistant message the round produced, so a caller can see
which round spent what -- and so the legacy projection can hand adopters the
same per-message usage_metadata the legacy body returns.
Three rules keep it truthful:
- Absent is
None, not0. A provider that reported nothing leavesMessage.usageNone; a dimension it did not report staysNonehere. A reported0stays0.UsageDeltaandTokenUsagecannot tell the two apart, which is why this type does not reuse them. - The provider's dict survives verbatim.
reportedis a deep copy of LangChain'susage_metadata, so provider detail this type has no typed field for (audio, the 5-minute ephemeral split, whatever comes next) is carried rather than dropped. - Only a round's own usage. Usage spent without closing a message -- an
empty terminal synthesis -- reaches the aggregate and no message. The
per-message sum may therefore be less than
AgentResult.usage; it is never more, and no round is credited with another's tokens.
MessageUsage ¶
Bases: BaseModel
One round's provider-reported usage; None fields were not reported.
The cache counts are inside input_tokens exactly as the provider
reports them -- see UsageDelta -- so a consumer must not add them on top.
from_reported
classmethod
¶
Project LangChain usage_metadata; None when nothing was reported.
Source code in src/symfonic/agent/message_usage.py
of
classmethod
¶
The usage a provider response (AIMessage or chunk) carries.