mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-29 15:31:38 +08:00
Compare commits
1 Commits
main
...
fix/analyt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18e6cd9938 |
@@ -2212,7 +2212,7 @@ async def get_usage_analytics(days: int = 30):
|
|||||||
cutoff = time.time() - (days * 86400)
|
cutoff = time.time() - (days * 86400)
|
||||||
cur = db._conn.execute("""
|
cur = db._conn.execute("""
|
||||||
SELECT date(started_at, 'unixepoch') as day,
|
SELECT date(started_at, 'unixepoch') as day,
|
||||||
SUM(input_tokens) as input_tokens,
|
SUM(input_tokens + COALESCE(cache_read_tokens, 0) + COALESCE(cache_write_tokens, 0)) as input_tokens,
|
||||||
SUM(output_tokens) as output_tokens,
|
SUM(output_tokens) as output_tokens,
|
||||||
SUM(cache_read_tokens) as cache_read_tokens,
|
SUM(cache_read_tokens) as cache_read_tokens,
|
||||||
SUM(reasoning_tokens) as reasoning_tokens,
|
SUM(reasoning_tokens) as reasoning_tokens,
|
||||||
@@ -2227,18 +2227,18 @@ async def get_usage_analytics(days: int = 30):
|
|||||||
|
|
||||||
cur2 = db._conn.execute("""
|
cur2 = db._conn.execute("""
|
||||||
SELECT model,
|
SELECT model,
|
||||||
SUM(input_tokens) as input_tokens,
|
SUM(input_tokens + COALESCE(cache_read_tokens, 0) + COALESCE(cache_write_tokens, 0)) as input_tokens,
|
||||||
SUM(output_tokens) as output_tokens,
|
SUM(output_tokens) as output_tokens,
|
||||||
COALESCE(SUM(estimated_cost_usd), 0) as estimated_cost,
|
COALESCE(SUM(estimated_cost_usd), 0) as estimated_cost,
|
||||||
COUNT(*) as sessions,
|
COUNT(*) as sessions,
|
||||||
SUM(COALESCE(api_call_count, 0)) as api_calls
|
SUM(COALESCE(api_call_count, 0)) as api_calls
|
||||||
FROM sessions WHERE started_at > ? AND model IS NOT NULL
|
FROM sessions WHERE started_at > ? AND model IS NOT NULL
|
||||||
GROUP BY model ORDER BY SUM(input_tokens) + SUM(output_tokens) DESC
|
GROUP BY model ORDER BY SUM(input_tokens + COALESCE(cache_read_tokens, 0) + COALESCE(cache_write_tokens, 0)) + SUM(output_tokens) DESC
|
||||||
""", (cutoff,))
|
""", (cutoff,))
|
||||||
by_model = [dict(r) for r in cur2.fetchall()]
|
by_model = [dict(r) for r in cur2.fetchall()]
|
||||||
|
|
||||||
cur3 = db._conn.execute("""
|
cur3 = db._conn.execute("""
|
||||||
SELECT SUM(input_tokens) as total_input,
|
SELECT SUM(input_tokens + COALESCE(cache_read_tokens, 0) + COALESCE(cache_write_tokens, 0)) as total_input,
|
||||||
SUM(output_tokens) as total_output,
|
SUM(output_tokens) as total_output,
|
||||||
SUM(cache_read_tokens) as total_cache_read,
|
SUM(cache_read_tokens) as total_cache_read,
|
||||||
SUM(reasoning_tokens) as total_reasoning,
|
SUM(reasoning_tokens) as total_reasoning,
|
||||||
|
|||||||
@@ -750,6 +750,49 @@ class TestNewEndpoints:
|
|||||||
"top_skills": [],
|
"top_skills": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def test_analytics_usage_includes_cache_tokens_in_input(self):
|
||||||
|
"""input_tokens in the response must include cache_read + cache_write."""
|
||||||
|
from hermes_state import SessionDB
|
||||||
|
|
||||||
|
db = SessionDB()
|
||||||
|
try:
|
||||||
|
db.create_session(
|
||||||
|
session_id="cache-tok-test",
|
||||||
|
source="cli",
|
||||||
|
model="claude-opus-4-6",
|
||||||
|
)
|
||||||
|
db.update_token_counts(
|
||||||
|
"cache-tok-test",
|
||||||
|
input_tokens=10,
|
||||||
|
output_tokens=50,
|
||||||
|
cache_read_tokens=9000,
|
||||||
|
cache_write_tokens=1000,
|
||||||
|
billing_provider="anthropic",
|
||||||
|
model="claude-opus-4-6",
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
db.close()
|
||||||
|
|
||||||
|
resp = self.client.get("/api/analytics/usage?days=7")
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
|
||||||
|
# Totals: input must be 10 + 9000 + 1000 = 10010
|
||||||
|
assert data["totals"]["total_input"] == 10010
|
||||||
|
assert data["totals"]["total_output"] == 50
|
||||||
|
|
||||||
|
# Daily: find the entry and verify
|
||||||
|
assert len(data["daily"]) == 1
|
||||||
|
day = data["daily"][0]
|
||||||
|
assert day["input_tokens"] == 10010
|
||||||
|
assert day["output_tokens"] == 50
|
||||||
|
|
||||||
|
# By-model: verify the model row
|
||||||
|
assert len(data["by_model"]) == 1
|
||||||
|
model_row = data["by_model"][0]
|
||||||
|
assert model_row["input_tokens"] == 10010
|
||||||
|
assert model_row["output_tokens"] == 50
|
||||||
|
|
||||||
def test_analytics_usage_includes_skill_breakdown(self):
|
def test_analytics_usage_includes_skill_breakdown(self):
|
||||||
from hermes_state import SessionDB
|
from hermes_state import SessionDB
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user