Skip to content

fix(viewer): correct Token Savings calculation to match CLI#721

Open
strugglerrr wants to merge 1 commit into
rohitg00:mainfrom
strugglerrr:fix/viewer-token-savings-calculation
Open

fix(viewer): correct Token Savings calculation to match CLI#721
strugglerrr wants to merge 1 commit into
rohitg00:mainfrom
strugglerrr:fix/viewer-token-savings-calculation

Conversation

@strugglerrr
Copy link
Copy Markdown

@strugglerrr strugglerrr commented May 29, 2026

Problem

The Viewer dashboard shows Token Savings: 0% even when agentmemory status reports significant savings (e.g., 53%).

Root Cause

The calculation formulas are inconsistent:

Source Formula Result (46 obs, 26 sessions)
CLI (correct) min(totalObs, 50) * 38 1,748 tokens
Viewer (buggy) sessions.length * tokenBudget 52,000 tokens

The Viewer uses sessions.length * 2000 which vastly overestimates injected tokens, causing savings to be negative (clamped to 0%).

Fix

Changed Viewer calculation to match CLI:

// Before (incorrect)
var estInjected = d.sessions.length * tokenBudget;

// After (correct)
var estInjected = Math.min(totalObs, 50) * 38;

Verification

After fix:

  • totalObs = 46
  • estFull = 46 * 80 = 3,680
  • estInjected = min(46, 50) * 38 = 1,748
  • savings = (1 - 1748/3680) * 100 = 52.5%

Now matches agentmemory status output.

Summary by CodeRabbit

  • Bug Fixes
    • Updated the Token Savings calculation in the dashboard. The estimation logic has been refined for improved accuracy, which may result in different savings percentages and cost figures displayed in the Token Savings stat card.

Review Change Stack

The Viewer was calculating Token Savings incorrectly:
- Before: estInjected = sessions.length * tokenBudget (default 2000)
- After: estInjected = min(totalObs, 50) * 38

This matches the calculation in cli.mjs and produces accurate savings
estimates. The old formula vastly overestimated injected tokens, causing
savings to show 0% even when significant savings existed.

Fixes the discrepancy between 'agentmemory status' (correct) and Viewer
dashboard (always showed 0%).
@vercel
Copy link
Copy Markdown

vercel Bot commented May 29, 2026

@strugglerrr is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

📝 Walkthrough

Walkthrough

The PR updates the dashboard "Token Savings" estimation logic to compute injected tokens based on a capped observation count multiplied by a fixed rate, replacing the previous session-count-based estimate. This change affects the displayed savings percentage and cost string in the Token Savings stat card.

Changes

Token Savings Estimation Update

Layer / File(s) Summary
Token Savings estimation calculation
src/viewer/index.html
The estInjected calculation in renderDashboard() changes from d.sessions.length * tokenBudget to Math.min(totalObs, 50) * 38, altering the computed savings percentage and cost string displayed in the Token Savings stat card.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 A cap on observations so keen,
Fifty's the max that we've foreseen,
Times thirty-eight tokens each gleams,
Savings now dance through dashboards' dreams!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: correcting the Token Savings calculation formula in the viewer to match the CLI implementation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/viewer/index.html (1)

1357-1358: ⚡ Quick win

Extract magic numbers to named constants for clarity.

The constants 80, 50, and 38 in the token savings formula are not self-documenting. Extracting them to named constants would make the calculation more understandable and easier to maintain.

♻️ Proposed refactor
+      var TOKENS_PER_OBS_FULL = 80;
+      var TOKENS_PER_OBS_INJECTED = 38;
+      var MAX_OBS_FOR_INJECTION = 50;
       var totalObs = d.sessions.reduce(function(a, s) { return a + (s.observationCount || 0); }, 0);
-      var tokenBudget = parseInt(new URLSearchParams(window.location.search).get('tokenBudget') || '2000', 10) || 2000;
-      var estFull = totalObs * 80;
-      var estInjected = Math.min(totalObs, 50) * 38;
+      var estFull = totalObs * TOKENS_PER_OBS_FULL;
+      var estInjected = Math.min(totalObs, MAX_OBS_FOR_INJECTION) * TOKENS_PER_OBS_INJECTED;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/viewer/index.html` around lines 1357 - 1358, Extract the magic numbers in
the token savings calculation into named constants: replace the literal 80 with
a descriptive constant like TOKENS_PER_OBS_FULL, 50 with MAX_INJECTED_OBS (or
similar), and 38 with TOKENS_PER_OBS_INJECTED; declare these constants near the
top of the script or above the block where estFull and estInjected are computed,
then update the formulas to use these constants (estFull = totalObs *
TOKENS_PER_OBS_FULL and estInjected = Math.min(totalObs, MAX_INJECTED_OBS) *
TOKENS_PER_OBS_INJECTED) so the intent of estFull, estInjected, and totalObs is
clear and maintainable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/viewer/index.html`:
- Line 1356: Remove the dead local variable tokenBudget: the parseInt(...)
assignment to tokenBudget is no longer used after the change that hardcodes 38
in the subsequent calculation, so delete the var tokenBudget = ... statement
(remove any reference to tokenBudget) to avoid confusing dead code; ensure no
other code in index.html references tokenBudget before committing.

---

Nitpick comments:
In `@src/viewer/index.html`:
- Around line 1357-1358: Extract the magic numbers in the token savings
calculation into named constants: replace the literal 80 with a descriptive
constant like TOKENS_PER_OBS_FULL, 50 with MAX_INJECTED_OBS (or similar), and 38
with TOKENS_PER_OBS_INJECTED; declare these constants near the top of the script
or above the block where estFull and estInjected are computed, then update the
formulas to use these constants (estFull = totalObs * TOKENS_PER_OBS_FULL and
estInjected = Math.min(totalObs, MAX_INJECTED_OBS) * TOKENS_PER_OBS_INJECTED) so
the intent of estFull, estInjected, and totalObs is clear and maintainable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 58b1979b-75f9-47f9-b6a2-19e37eca215b

📥 Commits

Reviewing files that changed from the base of the PR and between fd9e3bd and aed69af.

📒 Files selected for processing (1)
  • src/viewer/index.html

Comment thread src/viewer/index.html
@@ -1355,7 +1355,7 @@ <h1>agentmemory</h1>
var totalObs = d.sessions.reduce(function(a, s) { return a + (s.observationCount || 0); }, 0);
var tokenBudget = parseInt(new URLSearchParams(window.location.search).get('tokenBudget') || '2000', 10) || 2000;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove unused tokenBudget variable.

The tokenBudget variable is no longer used after the formula change on line 1358. The new calculation uses the constant 38 instead of the query parameter value, making this line dead code that can confuse future maintainers.

🧹 Proposed fix
       var totalObs = d.sessions.reduce(function(a, s) { return a + (s.observationCount || 0); }, 0);
-      var tokenBudget = parseInt(new URLSearchParams(window.location.search).get('tokenBudget') || '2000', 10) || 2000;
       var estFull = totalObs * 80;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var tokenBudget = parseInt(new URLSearchParams(window.location.search).get('tokenBudget') || '2000', 10) || 2000;
var totalObs = d.sessions.reduce(function(a, s) { return a + (s.observationCount || 0); }, 0);
var estFull = totalObs * 80;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/viewer/index.html` at line 1356, Remove the dead local variable
tokenBudget: the parseInt(...) assignment to tokenBudget is no longer used after
the change that hardcodes 38 in the subsequent calculation, so delete the var
tokenBudget = ... statement (remove any reference to tokenBudget) to avoid
confusing dead code; ensure no other code in index.html references tokenBudget
before committing.

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.

1 participant