Skip to content

feat(sdk): richer session-stats snapshot - #9

Merged
matej21 merged 1 commit into
mainfrom
feat/session-stats-metrics
Jul 30, 2026
Merged

feat(sdk): richer session-stats snapshot#9
matej21 merged 1 commit into
mainfrom
feat/session-stats-metrics

Conversation

@matej21

@matej21 matej21 commented Jul 30, 2026

Copy link
Copy Markdown
Member

What

Extends the session-stats SDK plugin snapshot with the counters the consuming
platform needs for per-day cost/usage reporting:

  • cacheReadTokens / cacheWriteTokens — from inference_completed and
    auxiliary_inference_completed metrics (cachedTokens, cacheWriteTokens),
    so cached prompt tokens can be billed/charted apart from fresh ones.
  • userMessages — from user_chat_message_received (user-chat plugin).
  • compactions — from context_compacted (context-compact plugin).
  • byAgent: Record<definitionName, { llmCalls, promptTokens, completionTokens, totalCost }>
    per agent-definition LLM breakdown.

byAgent needed no architecture change: state slices already receive the
session state as the third reducer argument, and the core reducer runs before
plugin slices (composeReducers(coreReducer, …)), so
sessionState.agents.get(event.agentId).definitionName is already populated
when the inference event is reduced.

Compatibility

  • All new fields default to 0 / {} in createInitialStats().
  • Plugin state is always reconstructed by replaying events through the reducer
    (no persisted state snapshots), so existing sessions pick the new counters up
    on the next replay instead of hitting undefined.
  • The snapshot travels verbatim in GET /status (metrics: s.metrics), so no
    transport contract change is needed.
  • ProviderStats / AgentStats are now exported from the package root.

Verification

  • bun run ts:build — clean (exit 0)
  • bun run lint — exit 0 (one pre-existing warning in
    plugins/uploads/preprocessors/markitdown-preprocessor.ts, untouched here)
  • bun test packages/sdk/src — 866 pass, 4 skip, 0 fail
  • bun test packages/*/src packages/*/tests — 922 pass, 8 skip, 0 fail

New plugins/session-stats/plugin.test.ts covers each new counter (defaults,
user messages, compactions, cache read/write incl. providers that report
neither, the per-agent breakdown across two definitions plus an auxiliary call,
and a regression check on the pre-existing counters).

🤖 Generated with Claude Code

https://claude.ai/code/session_018yiScAyGwDx3A3DqaUasEA

…ent usage

Session stats only exposed aggregate token/cost counters, so consumers could
not tell cached prompt tokens from fresh ones, could not count user turns or
compactions, and had no per-agent-definition breakdown of spend.

The reducer already receives the post-core-reducer session state, so the
spawning agent's definitionName is reachable from the inference events without
any structural change.

All new fields start at 0 / {} and state is always replayed from events, so
existing sessions keep working.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018yiScAyGwDx3A3DqaUasEA
@matej21
matej21 merged commit acd01c9 into main Jul 30, 2026
1 check passed
@matej21
matej21 deleted the feat/session-stats-metrics branch July 30, 2026 15:00
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