Skip to content

feat(miner): extract and persist real coding-agent token usage - #5658

Merged
JSONbored merged 2 commits into
mainfrom
miner-real-token-usage
Jul 13, 2026
Merged

feat(miner): extract and persist real coding-agent token usage#5658
JSONbored merged 2 commits into
mainfrom
miner-real-token-usage

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Agent SDK driver now reads real input_tokens/output_tokens off the SDK's own result message (usage field) instead of never reporting tokens
  • CLI-subprocess driver ports src/selfhost/ai.ts's extractCliUsage to scan CLI JSON/JSONL stdout for input/output/total token keys (top-level and nested usage/token_usage/etc.), same convention already used there for cost
  • iterate-loop.ts sums each iteration's real tokensUsed into finalMeterTotals.tokens (previously hardcoded to 0)
  • attempt-cli.js surfaces the accumulated total as totalTokensUsed on the attempt result and persists it on the attempt_outcome_summary ledger event, alongside the existing costUsd/provider fields feeding the Grafana miner-usage dashboard

Absent (not zero) is preserved as the "no signal reported" case throughout, mirroring costUsd's existing honest-absence convention.

Closes #5653

Test plan

  • packages/gittensory-engine node:test suite (537/537 pass)
  • Root vitest mirrors for both drivers + miner-attempt-runner/miner-attempt-cli (136/136 pass)
  • npm run test:ci green
  • npm run test:coverage (unsharded) — 100% branch coverage on every new/changed line, verified directly against lcov.info
  • npm run typecheck, npm run build:miner, npm run test:miner-pack, npm audit --audit-level=moderate all clean

Both driver implementations now report a real tokensUsed count instead of
always leaving it 0: the Agent SDK driver reads usage.input_tokens/
output_tokens off the SDK's own result message, and the CLI-subprocess
driver ports src/selfhost/ai.ts's extractCliUsage to scan CLI JSON/JSONL
stdout for the same signal. iterate-loop.ts sums this per-iteration total
into finalMeterTotals.tokens (previously hardcoded 0), and attempt-cli.js
surfaces it as totalTokensUsed and persists it on the attempt_outcome_summary
ledger event alongside the existing cost/provider fields.

Closes #5653
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 1fbf677 Commit Preview URL

Branch Preview URL
Jul 13 2026, 09:40 PM

@loopover-orb loopover-orb Bot added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. labels Jul 13, 2026
@loopover-orb

loopover-orb Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-13 22:17:23 UTC

11 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): packages/gittensory-engine/src/miner/agent-sdk-driver.ts (matched packages/gittensory-engine/**), packages/gittensory-engine/src/miner/cli-subprocess-driver.ts (matched packages/gittensory-engine/**), packages/gittensory-engine/src/miner/coding-agent-driver.ts (matched packages/gittensory-engine/**), packages/gittensory-engine/src/miner/iterate-loop.ts (matched packages/gittensory-engine/**), packages/gittensory-engine/test/agent-sdk-driver.test.ts (matched packages/gittensory-engine/**).

Review summary
This PR wires real token-usage extraction through both coding-agent drivers (SDK result-message usage field, CLI stdout JSON/JSONL scan) and threads the totals through iterate-loop's meter accumulation into the attempt_outcome_summary ledger event, following the exact same honest-absence convention already established for costUsd. The implementation is careful: totalTokensFromUsage/tokensFromResultMessage both return undefined rather than fabricating 0, the CLI extractor's key-list/nested-object approach mirrors src/selfhost/ai.ts's existing extractCliUsage as documented, and iterate-loop.ts's accumulation now correctly sums driverResult.tokensUsed instead of hardcoding 0. Tests are updated across every call site to supply finalMeterTotals so the previously-passing mocked loopResult objects don't silently regress, and new coverage is added for both drivers' undefined/malformed/partial-usage branches. Closes #5653 as claimed and stays narrowly scoped to that issue.

Nits — 7 non-blocking
  • packages/gittensory-engine/src/miner/cli-subprocess-driver.ts: the CLI JSONL scan takes `Math.max` per key across every line/nested-object seen (mergeCliUsage's maxNumber), which is fine for a monotonically-increasing cumulative counter but could silently pick a stale high-water value if a CLI ever resets/re-reports a lower running total mid-stream — worth a one-line comment confirming this is intentional (cumulative, not last-write-wins) since it's not obvious from the diff alone.
  • totalTokensFromUsage's 'prefer total_tokens over input+output sum' rule (packages/gittensory-engine/src/miner/cli-subprocess-driver.ts) is asymmetric with mergeCliUsage's own max-across-keys behavior for cost — consider a one-line note on why tokens dedupe against double-counting but cost does not need the same treatment.
  • packages/gittensory-miner/lib/attempt-cli.js is now ~504 lines per the size-smell flag; not a defect, but worth watching if more usage fields get bolted on here.
  • Consider extracting the shared CLI-usage key-list/merge logic between src/selfhost/ai.ts and cli-subprocess-driver.ts into one module now that both duplicate the same convention twice, even if the no-src-import rule is intentional — a follow-up issue reference would help future readers understand why the duplication is permanent.
  • In iterate-loop.ts, a short inline comment at the `tokens: driverResult.tokensUsed ?? 0` line confirming this differs from costUsd's undefined-preserving contract (tokens is zeroed per-iteration for accumulation, not left undefined) would preempt confusion since the two fields now have subtly different absence semantics at this layer.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #5653
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 45 registered-repo PR(s), 36 merged, 333 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 45 PR(s), 333 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Improvement ✅ Minor risk: clean · value: minor — Code changes are accompanied by test evidence.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, JavaScript, MDX, Shell, Solidity
  • Official Gittensor activity: 45 PR(s), 333 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
[BETA] Chat with Gittensory

Ask Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @gittensory ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @gittensory chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @gittensory mention with a real question is routed to the closest matching read-only command automatically -- no exact syntax required.

Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 13, 2026
… type

attempt-cli.js's runtime finalResult object already carries this field
(the previous commit) but the hand-maintained .d.ts was missed.
@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.03%. Comparing base (0dfc40a) to head (1fbf677).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5658   +/-   ##
=======================================
  Coverage   95.03%   95.03%           
=======================================
  Files         577      577           
  Lines       45920    45946   +26     
  Branches    14695    14708   +13     
=======================================
+ Hits        43639    43665   +26     
  Misses       1528     1528           
  Partials      753      753           
Flag Coverage Δ
shard-1 43.98% <81.08%> (+0.02%) ⬆️
shard-2 35.67% <29.72%> (-0.01%) ⬇️
shard-3 32.18% <8.10%> (-0.02%) ⬇️
shard-4 32.57% <27.02%> (-0.01%) ⬇️
shard-5 31.78% <37.83%> (+<0.01%) ⬆️
shard-6 44.44% <8.10%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...es/gittensory-engine/src/miner/agent-sdk-driver.ts 100.00% <100.00%> (ø)
...ttensory-engine/src/miner/cli-subprocess-driver.ts 100.00% <100.00%> (ø)
...gittensory-engine/src/miner/coding-agent-driver.ts 100.00% <ø> (ø)
...ckages/gittensory-engine/src/miner/iterate-loop.ts 74.32% <100.00%> (+0.35%) ⬆️
packages/gittensory-miner/lib/attempt-cli.js 96.96% <ø> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JSONbored
JSONbored merged commit 1e0ac6c into main Jul 13, 2026
19 checks passed
@JSONbored
JSONbored deleted the miner-real-token-usage branch July 13, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. gittensor:priority Maintainer-selected Gittensor priority — scores a 1.5x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract and persist real coding-agent token usage (Agent SDK usage.input_tokens/output_tokens, CLI JSON output)

1 participant