PostHog / PostHog/ai-plugin

SessionEnd capture omits subagent token usage (Task tool, multi-agent workflows, looped runs) — only the main-session transcript is parsed

Open
#166 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
84
Forks
15
Avg merge
14h 34m
Merged PRs (30d)
7

Description

Summary

The Claude Code SessionEnd capture only parses the single main-session transcript. Any generation that runs in a subagent — the Task tool, multi-agent workflows, and looped/iterative agent runs that spawn subagents — is silently dropped. For subagent-heavy sessions this omits the majority of token usage from PostHog.

Environment
  • PostHog/ai-plugin (default branch)
  • Recent Claude Code (subagent transcripts stored in a separate directory — see below)
Root cause

Recent Claude Code stores transcripts in two places:

  • Main session: ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl
  • Subagents: ~/.claude/projects/<encoded-cwd>/<session-id>/subagents/agent-<id>.jsonl (one file per subagent, each with a .meta.json sidecar)

Subagent turns are not duplicated into the main session file (the main file contains no isSidechain: true entries). Each subagent file carries its own assistant entries with full usage (input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens).

find_session_log(session_id, cwd) in posthog_llma/parser.py resolves only <session-id>.jsonl directly, then falls back to a single-level glob */{session_id}.jsonl. Neither reaches the subagent files — they're one directory deeper and named agent-<id>.jsonl, not <session-id>.jsonl. parse_session then reads that one file only. hooks/session-end-llma.py reconstructs the path via find_session_log and does not use the transcript_path provided in the hook payload.

There are no references to subagents, agent-*.jsonl, isSidechain, sidechain, agentId, or the Task tool anywhere in the capture path.

Reproduction
  1. Run a Claude Code session that spawns one or more subagents (invoke the Task tool / a multi-agent workflow / a loop that delegates to subagents).
  2. Let the SessionEnd hook fire.
  3. Inspect ~/.claude/projects/<encoded-cwd>/<session-id>/subagents/ — the agent-*.jsonl files contain assistant usage entries.
  4. Compare against the $ai_generation events that reached PostHog: none of the subagent generations appear; captured token totals match only the main <session-id>.jsonl.
Expected vs. actual
  • Expected: token usage for all generations in the session, including subagents, is captured.
  • Actual: only main-session generations are captured; all subagent usage is omitted.
Impact

For sessions using multi-agent workflows or Task-tool delegation — where most of the work runs in subagents — the reported spend can understate actual token usage by a large margin.

Suggested fix

After locating the main session file, also enumerate <encoded-cwd>/<session-id>/subagents/agent-*.jsonl, parse each, and merge their generations/spans into the result. Subagent entries already carry usage, the parent sessionId, and promptId; the .meta.json sidecar provides an agent slug/id that could tag events (e.g. an is_subagent / agent-name property) so main vs. subagent spend can be split in PostHog.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in posthog_llma/parser.py with find_session_log and parse_session, then inspect hooks/session-end-llama.py to see how the hook reconstructs the transcript path. Reproduce a SessionEnd capture with subagents and inspect the agent-*.jsonl files and their usage entries. Done means PostHog receives token usage from the main session and all subagent transcripts.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
ai, observability-sre
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.