From 6cd4280168533b7f4d96cf893d2fb94f5513a4c4 Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 3 Apr 2026 19:29:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20NemoClaw=20Claude=20API=20?= =?UTF-8?q?=E5=8A=A0=20token+=E8=B2=BB=E7=94=A8=E7=B5=B1=E8=A8=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Haiku 4.5: Input $0.80/1M, Output $4.00/1M 每次回覆顯示: token 數 | 本次費用 | 本月累計 Redis key: claude_cost:YYYY-MM,TTL 40 天 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/chat_manager.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/apps/api/src/services/chat_manager.py b/apps/api/src/services/chat_manager.py index 7cf483cc..37a8f298 100644 --- a/apps/api/src/services/chat_manager.py +++ b/apps/api/src/services/chat_manager.py @@ -176,7 +176,30 @@ class ChatManager: ) resp.raise_for_status() data = resp.json() - return data["content"][0]["text"].strip() + text = data["content"][0]["text"].strip() + + # Token/費用統計 — Claude Haiku 4.5: Input $0.80/1M, Output $4.00/1M + usage = data.get("usage", {}) + in_tok = usage.get("input_tokens", 0) + out_tok = usage.get("output_tokens", 0) + cost = (in_tok * 0.0000008) + (out_tok * 0.000004) + + # 月累計到 Redis + from src.core.redis_client import get_redis + from src.utils.timezone import now_taipei + redis = get_redis() + month_key = f"claude_cost:{now_taipei().strftime('%Y-%m')}" + try: + current = float(await redis.get(month_key) or 0) + new_total = current + cost + await redis.set(month_key, str(round(new_total, 6)), ex=40 * 24 * 3600) + except Exception: + new_total = cost + + logger.info("nemotron_claude_usage", in_tokens=in_tok, out_tokens=out_tok, + cost_usd=round(cost, 6), monthly_total_usd=round(new_total, 4)) + + return f"{text}\n\n📊 {in_tok+out_tok} tokens | ${cost:.4f} | 本月累計 ${new_total:.4f}" except Exception as e: logger.warning("nemotron_chat_failed", error=str(e)) return None