Skip to content

feat(agent): emit per-category context token breakdown#2352

Draft
k11kirky wants to merge 1 commit into
posthog-code/usage-threshold-monitorfrom
posthog-code/context-breakdown-data
Draft

feat(agent): emit per-category context token breakdown#2352
k11kirky wants to merge 1 commit into
posthog-code/usage-threshold-monitorfrom
posthog-code/context-breakdown-data

Conversation

@k11kirky
Copy link
Copy Markdown
Contributor

@k11kirky k11kirky commented May 25, 2026

Problem

The context usage indicator in the renderer showed only aggregate token counts (used / size / percentage) with no breakdown of where those tokens were coming from. Users had no way to see how much of the context window was consumed by the system prompt, tools, rules, conversation history, etc.

Changes

Agent-side (packages/agent):

  • Added context-breakdown.ts with a lightweight character-ratio token estimator (~3.5 chars/token) and helpers:
    • estimateTokens / estimateJsonTokens for cheap client-side estimation
    • estimateSystemPrompt handles raw strings, { type: "preset", append } objects, and undefined, adding a constant CLAUDE_PRESET_ESTIMATE_TOKENS (4000) when the opaque Claude preset is in use
    • buildBreakdown derives the conversation bucket as whatever input tokens remain after subtracting the stable pieces (system prompt, tools, rules, skills, MCP, subagents), floored at 0 to absorb estimation drift
    • emptyBaseline / ContextBreakdownBaseline types for initializing and carrying per-source estimates across turns
  • Attached a contextBreakdownBaseline to the Session type, initialized at session start with the estimated system-prompt token count
  • Emits the breakdown alongside the existing _posthog/usage_update notification after each model turn, using the result's own input token categories rather than the streamed delta to handle subagent turns correctly

Renderer-side (apps/code):

  • Extended ContextUsage with a breakdown: ContextBreakdown | null field and added the ContextBreakdown interface (mirroring the agent shape, kept local to avoid a cross-package dependency)
  • Refactored extractContextUsage to scan events in a single reverse pass, independently finding the latest aggregate (session/update) and the latest breakdown (_posthog/usage_update or __posthog/usage_update), then merging them

How did you test this?

  • Added unit tests for context-breakdown.ts covering estimateTokens, estimateJsonTokens, estimateSystemPrompt, and buildBreakdown (edge cases: empty input, circular JSON, conversation floored at 0, preset vs. raw string)
  • Added unit tests for extractContextUsage covering: no events, aggregate-only, merged breakdown, and the double-underscore method prefix variant

Publish to changelog?

no

Copy link
Copy Markdown
Contributor Author

k11kirky commented May 25, 2026

Adds a `breakdown` field to the `_posthog/usage_update` ext-notification
so the renderer can render per-source token splits in the upcoming
context-breakdown popover. The agent estimates token counts for the
stable pieces of the context (system prompt today; tools / MCP /
rules / skills / subagents will follow as the agent gets at-rest
access to their definitions) via a character-ratio heuristic. The
`conversation` bucket is derived as `max(0, currentInputTokens -
sum(stable))`, so the categories always sum to the input total.

The renderer's `useContextUsage` now scans backwards for both the
existing `session/update` aggregate and the new ext-notification's
breakdown, surfacing the latter as a nullable field. Existing callers
keep the aggregate; B4 wires the breakdown into the popover.

Generated-By: PostHog Code
Task-Id: bac06178-1ab1-4000-9a56-1901215bd4af

Generated-By: PostHog Code
Task-Id: bac06178-1ab1-4000-9a56-1901215bd4af
@k11kirky k11kirky force-pushed the posthog-code/usage-threshold-monitor branch from d6105bb to 1589fab Compare May 25, 2026 16:58
@k11kirky k11kirky force-pushed the posthog-code/context-breakdown-data branch from 78a3903 to 00f8802 Compare May 25, 2026 16:58
@Basit-Balogun10
Copy link
Copy Markdown

Basit-Balogun10 commented May 25, 2026

Hello @k11kirky 👋🏾
This PR and #2353 should close #2062, right?

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.

2 participants