mirror of
https://github.com/tiennm99/serena.git
synced 2026-08-08 22:25:38 +00:00
Minor improvements of stats display in dashboard
Display token count estimator name Display short message if no stats were collected
This commit is contained in:
committed by
Michael Panchenko
parent
f9609b8d9f
commit
93702f3932
+11
-3
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import threading
|
||||
from abc import ABC
|
||||
from abc import ABC, abstractmethod
|
||||
from collections import defaultdict
|
||||
from copy import copy
|
||||
from dataclasses import asdict, dataclass
|
||||
@@ -15,6 +15,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TokenCountEstimator(ABC):
|
||||
@abstractmethod
|
||||
def estimate_token_count(self, text: str) -> int:
|
||||
"""
|
||||
Estimate the number of tokens in the given text.
|
||||
@@ -84,9 +85,9 @@ class RegisteredTokenCountEstimator(Enum):
|
||||
|
||||
def _create_estimator(self) -> TokenCountEstimator:
|
||||
match self:
|
||||
case self.TIKTOKEN_GPT4O:
|
||||
case RegisteredTokenCountEstimator.TIKTOKEN_GPT4O:
|
||||
return TiktokenCountEstimator(model_name="gpt-4o")
|
||||
case self.ANTHROPIC_CLAUDE_SONNET_4:
|
||||
case RegisteredTokenCountEstimator.ANTHROPIC_CLAUDE_SONNET_4:
|
||||
return AnthropicTokenCount(model_name="claude-sonnet-4-20250514")
|
||||
case _:
|
||||
raise ValueError(f"Unknown token count estimator: {self.value}")
|
||||
@@ -110,6 +111,13 @@ class ToolUsageStats:
|
||||
self._tool_stats: dict[str, ToolUsageStats.Entry] = defaultdict(ToolUsageStats.Entry)
|
||||
self._tool_stats_lock = threading.Lock()
|
||||
|
||||
@property
|
||||
def token_estimator_name(self) -> str:
|
||||
"""
|
||||
Get the name of the registered token count estimator used.
|
||||
"""
|
||||
return self._token_estimator_name
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class Entry:
|
||||
num_times_called: int = 0
|
||||
|
||||
@@ -130,6 +130,11 @@ class SerenaDashboardAPI:
|
||||
self._clear_tool_stats()
|
||||
return {"status": "cleared"}
|
||||
|
||||
@self._app.route("/get_token_count_estimator_name", methods=["GET"])
|
||||
def get_token_count_estimator_name() -> dict[str, str]:
|
||||
estimator_name = self._tool_usage_stats.token_estimator_name if self._tool_usage_stats else "unknown"
|
||||
return {"token_count_estimator_name": estimator_name}
|
||||
|
||||
@self._app.route("/shutdown", methods=["PUT"])
|
||||
def shutdown() -> dict[str, str]:
|
||||
self._shutdown()
|
||||
@@ -150,7 +155,8 @@ class SerenaDashboardAPI:
|
||||
return ResponseToolStats(stats={})
|
||||
|
||||
def _clear_tool_stats(self) -> None:
|
||||
self._tool_usage_stats.clear()
|
||||
if self._tool_usage_stats is not None:
|
||||
self._tool_usage_stats.clear()
|
||||
|
||||
def _shutdown(self) -> None:
|
||||
log.info("Shutting down Serena")
|
||||
|
||||
@@ -201,18 +201,19 @@ class Dashboard {
|
||||
|
||||
loadStats() {
|
||||
let self = this;
|
||||
$.ajax({
|
||||
url: '/get_tool_stats',
|
||||
type: 'GET',
|
||||
success: function(response) {
|
||||
self.displayStats(response.stats || {});
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('Error loading stats:', error);
|
||||
}
|
||||
$.when(
|
||||
$.ajax({ url: '/get_tool_stats', type: 'GET' }),
|
||||
$.ajax({ url: '/get_token_count_estimator_name', type: 'GET' })
|
||||
).done(function(statsResp, estimatorResp) {
|
||||
const stats = statsResp[0].stats;
|
||||
const tokenCountEstimatorName = estimatorResp[0].token_count_estimator_name;
|
||||
self.displayStats(stats, tokenCountEstimatorName);
|
||||
}).fail(function() {
|
||||
console.error('Error loading stats or estimator name');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
clearStats() {
|
||||
let self = this;
|
||||
$.ajax({
|
||||
@@ -227,8 +228,27 @@ class Dashboard {
|
||||
});
|
||||
}
|
||||
|
||||
displayStats(stats) {
|
||||
displayStats(stats, tokenCountEstimatorName) {
|
||||
const names = Object.keys(stats);
|
||||
// If no stats collected
|
||||
if (names.length === 0) {
|
||||
// hide summary, charts, estimator name
|
||||
$('#stats-summary').hide();
|
||||
$('#estimator-name').hide();
|
||||
$('.charts-container').hide();
|
||||
// show no-stats message
|
||||
$('#no-stats-message').show();
|
||||
return;
|
||||
} else {
|
||||
// Ensure everything is visible
|
||||
$('#estimator-name').show();
|
||||
$('#stats-summary').show();
|
||||
$('.charts-container').show();
|
||||
$('#no-stats-message').hide();
|
||||
}
|
||||
|
||||
$('#estimator-name').html(`<strong>Token count estimator:</strong> ${tokenCountEstimatorName}`);
|
||||
|
||||
const counts = names.map(n => stats[n].num_times_called);
|
||||
const inputTokens = names.map(n => stats[n].input_tokens);
|
||||
const outputTokens = names.map(n => stats[n].output_tokens);
|
||||
@@ -252,18 +272,6 @@ class Dashboard {
|
||||
if (this.inputChart) this.inputChart.destroy();
|
||||
if (this.outputChart) this.outputChart.destroy();
|
||||
|
||||
if (names.length === 0) {
|
||||
this.countChart = null;
|
||||
this.tokensChart = null;
|
||||
this.inputChart = null;
|
||||
this.outputChart = null;
|
||||
countCtx.getContext('2d').clearRect(0,0,countCtx.width,countCtx.height);
|
||||
tokensCtx.getContext('2d').clearRect(0,0,tokensCtx.width,tokensCtx.height);
|
||||
inputCtx.getContext('2d').clearRect(0,0,inputCtx.width,inputCtx.height);
|
||||
outputCtx.getContext('2d').clearRect(0,0,outputCtx.width,outputCtx.height);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update summary table
|
||||
this.updateSummaryTable(totalCalls, totalInputTokens, totalOutputTokens);
|
||||
|
||||
|
||||
@@ -186,6 +186,11 @@
|
||||
</div>
|
||||
|
||||
<div id="stats-summary" style="margin-bottom:20px; text-align:center;"></div>
|
||||
<div id="estimator-name" style="text-align:center; margin-bottom:10px;"></div>
|
||||
<div id="no-stats-message" style="text-align:center; color:#666; font-style:italic; display:none;">
|
||||
No tool stats collected. Have you enabled tool stats collection in the configuration?
|
||||
</div>
|
||||
|
||||
|
||||
<div class="charts-container">
|
||||
<div class="chart-group">
|
||||
|
||||
Reference in New Issue
Block a user