feat: per-job token-usage capture via PostToolUse hook
update_job_status accepts optionele model_id + 4 token-velden conform het runbook-contract (mcp-integration.md:42). De waarden komen niet van de agent zelf maar van scripts/persist-job-usage.ts, een PostToolUse-hook die het lokale Claude Code transcript (~/.claude/projects/.../*.jsonl) leest en de usage tussen de laatste wait_for_job en update_job_status optelt. Geen Anthropic API-key nodig — alle data staat al lokaal op disk omdat Claude Code per assistant-message het API usage-blok logt (input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens + message.model). Robustness: - Subagent (isSidechain: true) lines worden geskipt om double-counting te voorkomen tegen subagents/-subdirectory transcripts. - Lines worden gededupliceerd op uuid (branching/resumption). - model_id wordt genormaliseerd: claude-opus-4-7[1m] -> claude-opus-4-7-1m zodat de [1m]-variant op een aparte model_prices-rij kan matchen. - Hook is non-blocking: elke fout logt een warning en exit 0. Hook-config in .claude/settings.json met SCRUM4ME_MCP_DIR-fallback zodat de agent vanuit een product-worktree (andere cwd) ook werkt mits de user de hook in ~/.claude/settings.json kopieert. 16 nieuwe vitest-cases voor parseTranscript, computeUsageFromTranscript, normalizeModelId en persistJobUsage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f5887da1f5
commit
25bd3dd62a
5 changed files with 573 additions and 1 deletions
17
CLAUDE.md
17
CLAUDE.md
|
|
@ -46,6 +46,23 @@ Or add to `~/.scrum4me-agent-config.json`:
|
|||
|
||||
If no repo root is found, `wait_for_job` rolls the claim back to QUEUED and returns an error.
|
||||
|
||||
## Token-usage capture (PostToolUse hook)
|
||||
|
||||
`update_job_status` accepts optional fields `model_id`, `input_tokens`, `output_tokens`, `cache_read_tokens`, `cache_write_tokens`. The agent never has to pass them — `scripts/persist-job-usage.ts` runs as a PostToolUse hook, reads the local Claude Code transcript JSONL (no Anthropic API needed), sums per-job usage, and writes directly to `claude_jobs` via Prisma. Window detection: from the most-recent `wait_for_job` tool_use to EOF.
|
||||
|
||||
The hook is registered in `.claude/settings.json` of this repo. **For agent-worker mode** (Claude Code running with cwd inside a product worktree, not scrum4me-mcp), copy the same hook block into your user settings (`~/.claude/settings.json`) and set `SCRUM4ME_MCP_DIR` so the script resolves regardless of cwd:
|
||||
|
||||
```bash
|
||||
export SCRUM4ME_MCP_DIR=/absolute/path/to/scrum4me-mcp
|
||||
```
|
||||
|
||||
Pricing rows (`model_prices`) are seeded by Scrum4Me's `prisma/seed.ts`. Unknown `model_id`s leave `cost_usd = NULL` in Insights queries — add a row and re-run `npm run seed` to fill them in.
|
||||
|
||||
Robustness notes:
|
||||
- Subagent (`isSidechain: true`) lines in the main JSONL are skipped to avoid double-counting against `subagents/`-subdirectory transcripts.
|
||||
- Lines are deduplicated on `uuid` because branching/resumption can rewrite the same message into multiple JSONLs.
|
||||
- Known Claude Code bug: auto-updates can silently delete files under `~/.claude/projects/`. If you depend on these numbers for billing/reporting, persist `claude_jobs.input_tokens` etc. immediately on `update_job_status` (already what this hook does) and consider an external backup of `~/.claude/projects/` if you want to retain historical detail.
|
||||
|
||||
## Manual worktree cleanup
|
||||
|
||||
Run `cleanup_my_worktrees` (no arguments) to scan `~/.scrum4me-agent-worktrees/` and remove worktrees for jobs that are in a terminal state (DONE, FAILED, CANCELLED). Worktrees for active jobs (QUEUED, CLAIMED, RUNNING) are left untouched. Returns `{ removed, kept, skipped }`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue