mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-23 05:31:23 +00:00
feat(dashboard): hide token/cost analytics behind config flag (default off) (#25438)
The Analytics page and the token/cost surfaces on the Models page show local debug estimates only. They count input+output (and a bar viz adds cache_read+reasoning, missing cache_write entirely) from successful main-agent responses that returned a usable usage block. Excluded silently: - All auxiliary calls — context compression, title generation, vision, session search, web extract, smart approvals, MCP routing, plugin LLM access (13 production call sites bypass update_token_counts) - Provider-side retries, fallback attempts - Any call whose usage block didn't come back - cache_write_tokens (column exists in sessions table but not returned by /api/analytics/models) Real-world impact: a user on Kimi K2.6 saw 150K local vs 27M on the OpenRouter side over the same window. Precise-looking numbers next to provider billing create false confidence and support load. This change adds dashboard.show_token_analytics (default False) to gate: - The Analytics nav item (hidden from sidebar when off) - The Analytics page (renders an explanation card instead of charts) - Token bars, totals, cost figures, avg/api_calls on the Models page The Models page keeps capability metadata (context window, vision, tools, reasoning), the use-as-main/aux menu, sessions count, and last-used timestamps when the flag is off. Set dashboard.show_token_analytics: true in config.yaml to opt back in to the local debug estimate. Fixing the underlying accounting (issue #23270) is a separate, larger workstream. Refs: #23270, #21705
This commit is contained in:
parent
e90508103c
commit
f7ad2f1115
4 changed files with 249 additions and 100 deletions
|
|
@ -75,6 +75,7 @@ import { PluginPage, PluginSlot, usePlugins } from "@/plugins";
|
|||
import type { PluginManifest } from "@/plugins";
|
||||
import { useTheme } from "@/themes";
|
||||
import { isDashboardEmbeddedChatEnabled } from "@/lib/dashboard-flags";
|
||||
import { api } from "@/lib/api";
|
||||
|
||||
function RootRedirect() {
|
||||
return <Navigate to="/sessions" replace />;
|
||||
|
|
@ -316,6 +317,21 @@ export default function App() {
|
|||
const isChatRoute = normalizedPath === "/chat";
|
||||
const embeddedChat = isDashboardEmbeddedChatEnabled();
|
||||
|
||||
// `dashboard.show_token_analytics` gates the Analytics nav item. The
|
||||
// page itself remains reachable by URL (it renders an explanation when
|
||||
// the flag is off — see AnalyticsPage), but hiding the nav entry avoids
|
||||
// surfacing misleading token/cost numbers in the sidebar. Default off.
|
||||
const [showTokenAnalytics, setShowTokenAnalytics] = useState(false);
|
||||
useEffect(() => {
|
||||
api
|
||||
.getConfig()
|
||||
.then((cfg) => {
|
||||
const dash = (cfg?.dashboard ?? {}) as { show_token_analytics?: unknown };
|
||||
setShowTokenAnalytics(dash.show_token_analytics === true);
|
||||
})
|
||||
.catch(() => setShowTokenAnalytics(false));
|
||||
}, []);
|
||||
|
||||
// A plugin can replace the built-in /chat page via `tab.override: "/chat"`
|
||||
// in its manifest. When one does, `buildRoutes` already swaps the route
|
||||
// element for <PluginPage /> — but we also have to suppress the
|
||||
|
|
@ -346,11 +362,12 @@ export default function App() {
|
|||
[embeddedChat],
|
||||
);
|
||||
|
||||
const builtinNav = useMemo(
|
||||
() =>
|
||||
embeddedChat ? [CHAT_NAV_ITEM, ...BUILTIN_NAV_REST] : BUILTIN_NAV_REST,
|
||||
[embeddedChat],
|
||||
);
|
||||
const builtinNav = useMemo(() => {
|
||||
const base = embeddedChat
|
||||
? [CHAT_NAV_ITEM, ...BUILTIN_NAV_REST]
|
||||
: BUILTIN_NAV_REST;
|
||||
return showTokenAnalytics ? base : base.filter((n) => n.path !== "/analytics");
|
||||
}, [embeddedChat, showTokenAnalytics]);
|
||||
|
||||
const sidebarNav = useMemo(
|
||||
() => partitionSidebarNav(builtinNav, manifests),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue