Skip to content

Add token metrics to DummyOptimizer find_tool responses#3821

Open
aponcedeleonch wants to merge 1 commit intomainfrom
optimizer-token-metrics
Open

Add token metrics to DummyOptimizer find_tool responses#3821
aponcedeleonch wants to merge 1 commit intomainfrom
optimizer-token-metrics

Conversation

@aponcedeleonch
Copy link
Member

Closes: #3820

Add TokenCounter abstraction and wire it into DummyOptimizer so that find_tool responses include TokenMetrics (baseline, returned, savings%).

Token counts are precomputed per-tool at optimizer construction time and the baseline total is cached as an immutable field, avoiding redundant summation on every FindTool call. The computeTokenMetrics helper operates entirely on optimizer-local state—no store involvement needed.

The TokenCounter interface lives in the optimizer package (not the internal types package) since only the optimizer layer uses it. CharDivTokenCounter provides the default heuristic (JSON byte length / 4).

Factory functions (NewDummyOptimizerFactory, NewDummyOptimizerFactoryWithStore) accept or create a TokenCounter and pass it through to NewDummyOptimizer.

Add TokenCounter abstraction and wire it into DummyOptimizer so that
find_tool responses include TokenMetrics (baseline, returned, savings%).

Token counts are precomputed per-tool at optimizer construction time and
the baseline total is cached as an immutable field, avoiding redundant
summation on every FindTool call. The computeTokenMetrics helper operates
entirely on optimizer-local state—no store involvement needed.

The TokenCounter interface lives in the optimizer package (not the
internal types package) since only the optimizer layer uses it.
CharDivTokenCounter provides the default heuristic (JSON byte length / 4).

Factory functions (NewDummyOptimizerFactory, NewDummyOptimizerFactoryWithStore)
accept or create a TokenCounter and pass it through to NewDummyOptimizer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions bot added the size/S Small PR: 100-299 lines changed label Feb 13, 2026
@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

❌ Patch coverage is 89.18919% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.85%. Comparing base (f1772c6) to head (70b034c).

Files with missing lines Patch % Lines
pkg/vmcp/optimizer/dummy_optimizer.go 92.59% 1 Missing and 1 partial ⚠️
pkg/vmcp/optimizer/token_counter.go 77.77% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3821      +/-   ##
==========================================
+ Coverage   66.84%   66.85%   +0.01%     
==========================================
  Files         439      440       +1     
  Lines       43509    43538      +29     
==========================================
+ Hits        29083    29108      +25     
- Misses      12175    12178       +3     
- Partials     2251     2252       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

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

LGTM but let's simplify the tests

tools map[string]server.ServerTool

// tokenCounts holds precomputed per-tool token estimates, indexed by tool name.
tokenCounts map[string]int
Copy link
Contributor

Choose a reason for hiding this comment

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

question, non-blocking: is this also immutable? Add a comment to explain.

Comment on lines 46 to 60
tests := []struct {
name string
tools []server.ServerTool
searchFunc func(ctx context.Context, query string, allowedTools []string) ([]ToolMatch, error)
upsertFunc func(ctx context.Context, tools []server.ServerTool) error
input FindToolInput
expectedNames []string
expectErr bool
errContains string
expectCreate bool // if false, expect NewDummyOptimizer to fail
createErr string
name string
tools []server.ServerTool
searchFunc func(ctx context.Context, query string, allowedTools []string) ([]ToolMatch, error)
upsertFunc func(ctx context.Context, tools []server.ServerTool) error
input FindToolInput
expectedNames []string
expectErr bool
errContains string
expectCreate bool // if false, expect NewDummyOptimizer to fail
createErr string
checkMetrics bool
expectBaseline int
expectReturned int
}{
Copy link
Contributor

Choose a reason for hiding this comment

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

Blocker: This table is getting quite complex 😵

Can we break it up into more focused tests so it's easier to read?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S Small PR: 100-299 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement TokenMetrics calculation in Optimizer

2 participants