Every session score is computed locally by the CLI from your session's telemetry, and the server independently recalculates it from the submitted dimension scores on every submission. If the recalculated score differs from the submitted one by more than 1 point, the submission is rejected. There is no hidden adjustment and no server-side tuning — this page is the whole formula.
Your session score is a weighted sum of five dimension scores, each 0–100:
score = savingsRate * 0.35
+ cacheEfficiency * 0.25
+ wasteControl * 0.20
+ summaryCoverage * 0.15
+ volumeBonus * 0.05
The result is clamped to 0–100 and rounded.
The fraction of raw output tokens that AgentOps saved by returning summaries instead of full output:
value = totalSavedTokens / totalRawTokens
score = min(100, (value / 0.6) * 100)
A 60% savings rate earns the full 100. This is the largest weight because token savings is the core job of the tool.
The local cache hit rate:
value = totalCacheHits / totalCacheLookups
score = value * 100
If there were zero cache lookups, this scores 0.
Penalizes detected waste patterns (for example, re-running the same expensive command repeatedly) relative to total commands:
wasteRatio = wastePatterns / totalCommands
value = max(0, 1 - wasteRatio * 5)
score = value * 100
One waste pattern per 5 commands zeroes this dimension out.
The fraction of command families (test, build, typescript, eslint, etc.) where more than half the commands got a compact summary:
value = familiesWithSummaryRate>0.5 / totalFamilies
score = value * 100
A small logarithmic bonus for real usage, capped at 100:
value = min(1, log2(totalCommands + 1) * 15 / 100)
score = value * 100
About 100 commands in a session maxes this out. At 5% weight it can never carry a score — it exists so a 2-command session doesn't outrank a 200-command one on ratios alone.
Grades map directly from the final score:
A session with zero commands or zero raw tokens scores 0 (F) and is flagged as limited data. Sessions with fewer than 3 commands are also flagged as limited data.
The server does not trust the submitted score. On every submission it checks:
savingsRate.value matches totalSavedTokens / totalRawTokens within 0.01cacheEfficiency.value matches totalCacheHits / totalCacheLookups within 0.01totalSavedTokens does not exceed totalRawTokenstotalRawTokensAny mismatch rejects the submission with a specific error. The validation source is public: server/src/validation.ts.
agentops score
prints the per-dimension values, scores, and weights for your latest session. agentops score --session <id> scores a specific session. The scoring source is public: src/core/scoring/sessionScorer.ts.