rename secrets.py to credential_store.py, enhance /status, add usage tracking

- Rename src/secrets.py → src/credential_store.py (avoid stdlib conflict)
- Enhanced /status command: uptime, tokens, cost, context window usage
- Session metadata now tracks input/output tokens, cost, duration
- _safe_env() changed from allowlist to blocklist approach
- Better Claude CLI error logging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MoltBot Service
2026-02-13 17:54:59 +00:00
parent 0ecfa630eb
commit 85c72e4b3d
7 changed files with 155 additions and 39 deletions

View File

@@ -41,11 +41,12 @@ PERSONALITY_FILES = [
"HEARTBEAT.md",
]
# Environment variables allowed through to the Claude subprocess
_ENV_PASSTHROUGH = {
"PATH", "HOME", "USER", "LANG", "LC_ALL", "TERM",
"SHELL", "TMPDIR", "XDG_CONFIG_HOME", "XDG_DATA_HOME",
"CLAUDE_CONFIG_DIR",
# Environment variables to REMOVE from Claude subprocess
# (secrets, tokens, and vars that cause nested-session errors)
_ENV_STRIP = {
"CLAUDECODE", "CLAUDE_CODE_SSE_PORT", "CLAUDE_CODE_ENTRYPOINT",
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS",
"DISCORD_TOKEN", "BOT_TOKEN", "API_KEY", "SECRET",
}
# ---------------------------------------------------------------------------
@@ -65,8 +66,8 @@ if not shutil.which(CLAUDE_BIN):
def _safe_env() -> dict[str, str]:
"""Return a filtered copy of os.environ for subprocess calls."""
return {k: v for k, v in os.environ.items() if k in _ENV_PASSTHROUGH}
"""Return os.environ minus sensitive/problematic variables."""
return {k: v for k, v in os.environ.items() if k not in _ENV_STRIP}
def _load_sessions() -> dict:
@@ -121,9 +122,11 @@ def _run_claude(cmd: list[str], timeout: int) -> dict:
raise TimeoutError(f"Claude CLI timed out after {timeout}s")
if proc.returncode != 0:
detail = proc.stderr[:500] or proc.stdout[:500]
logger.error("Claude CLI stdout: %s", proc.stdout[:1000])
logger.error("Claude CLI stderr: %s", proc.stderr[:1000])
raise RuntimeError(
f"Claude CLI error (exit {proc.returncode}): "
f"{proc.stderr[:500]}"
f"Claude CLI error (exit {proc.returncode}): {detail}"
)
try:
@@ -190,6 +193,9 @@ def start_session(
response_text = data["result"]
session_id = data["session_id"]
# Extract usage stats
usage = data.get("usage", {})
# Save session metadata
now = datetime.now(timezone.utc).isoformat()
sessions = _load_sessions()
@@ -199,6 +205,11 @@ def start_session(
"created_at": now,
"last_message_at": now,
"message_count": 1,
"total_input_tokens": usage.get("input_tokens", 0),
"total_output_tokens": usage.get("output_tokens", 0),
"total_cost_usd": data.get("total_cost_usd", 0),
"duration_ms": data.get("duration_ms", 0),
"context_tokens": usage.get("input_tokens", 0) + usage.get("output_tokens", 0),
}
_save_sessions(sessions)
@@ -226,6 +237,9 @@ def resume_session(
response_text = data["result"]
# Extract usage stats
usage = data.get("usage", {})
# Update session metadata
now = datetime.now(timezone.utc).isoformat()
sessions = _load_sessions()
@@ -233,6 +247,11 @@ def resume_session(
if session.get("session_id") == session_id:
session["last_message_at"] = now
session["message_count"] = session.get("message_count", 0) + 1
session["total_input_tokens"] = session.get("total_input_tokens", 0) + usage.get("input_tokens", 0)
session["total_output_tokens"] = session.get("total_output_tokens", 0) + usage.get("output_tokens", 0)
session["total_cost_usd"] = session.get("total_cost_usd", 0) + data.get("total_cost_usd", 0)
session["duration_ms"] = session.get("duration_ms", 0) + data.get("duration_ms", 0)
session["context_tokens"] = usage.get("input_tokens", 0) + usage.get("output_tokens", 0)
break
_save_sessions(sessions)