feat(dashboard): show Claude usage (tokens + requests) since server start

ClaudeBrain now returns per-reply token usage (Reply.usage from the API
response), the dashboard accumulates it (monitor.add_claude_usage), and the
header shows a "클로드 토큰" stat (input+output total, with a tooltip breaking
down input/output tokens and request count).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
EJClaw
2026-08-22 16:40:25 +09:00
parent 5d9161982f
commit f1f059a018
4 changed files with 28 additions and 1 deletions

View File

@@ -475,6 +475,9 @@ class Dashboard:
try:
reply = self._submit(self.brain.respond(heard, None, list(self._history)))
text = (reply.text or "").strip()
u = getattr(reply, "usage", None)
if u:
self.monitor.add_claude_usage(u.get("input", 0), u.get("output", 0))
except Exception as exc: # noqa: BLE001
log.exception("brain failed")
self.monitor.log("error", f"두뇌 응답 실패: {exc}")
@@ -723,6 +726,7 @@ PAGE = r"""<!DOCTYPE html>
<div class="stats">
<div class="stat"><b id="s-turns">0</b><span>대화 수</span></div>
<div class="stat"><b id="s-errors">0</b><span>오류</span></div>
<div class="stat" title="이 봇이 서버 시작 후 쓴 클로드 토큰"><b id="s-claude">0</b><span>클로드 토큰</span></div>
<div class="stat"><b id="s-up">0초</b><span>가동시간</span></div>
<div class="stat"><b id="s-conn">·</b><span>연결</span></div>
</div>
@@ -803,6 +807,7 @@ function fmtTime(wall){
return d.toLocaleTimeString('ko-KR',{hour12:false}) +
'.' + String(d.getMilliseconds()).padStart(3,'0');
}
function fmtNum(n){ n=n||0; if(n>=1e6) return (n/1e6).toFixed(2)+'M'; if(n>=1e3) return (n/1e3).toFixed(1)+'k'; return ''+n; }
function fmtUptime(s){
s = Math.floor(s||0);
const h=Math.floor(s/3600), m=Math.floor(s%3600/60), sec=s%60;
@@ -817,6 +822,10 @@ function renderStatus(s){
$('s-turns').textContent = s.turns_total ?? 0;
$('s-errors').textContent = s.errors_total ?? 0;
$('s-up').textContent = fmtUptime(s.uptime_s);
const ci=s.claude_input_tokens||0, co=s.claude_output_tokens||0, cr=s.claude_requests||0;
const cel=$('s-claude');
if(cel){ cel.textContent = fmtNum(ci+co);
cel.parentElement.title = '클로드 사용량 (서버 시작 후) — 입력 '+ci.toLocaleString()+' · 출력 '+co.toLocaleString()+' 토큰 · 요청 '+cr+''; }
const listening = s.listening;
$('dot').className = 'dot ' + (listening ? 'live' : 'off');
$('listen').textContent = listening ? '듣는 중' : (s.running ? '실행 중 (대기)' : '중지됨');