hermes-agent/hermes_cli/trace.py
Teknium 2aa908e867
feat(trace): upload sessions to HF Agent Trace Viewer
Salvage trace upload as a smaller CLI-first feature: deterministic Claude Code JSONL export, fail-closed redaction, lazy Hugging Face dependency, and no gateway slash-command wiring.
2026-07-06 06:01:17 -07:00

71 lines
2.2 KiB
Python

"""``hermes trace`` CLI subcommand — upload a session transcript to Hugging Face.
Thin CLI wrapper over :mod:`agent.trace_upload`. The heavy lifting (session
load, Claude Code JSONL conversion, HF upload) lives there so the command
handler stays small and deterministic.
Ported from qwibitai/nanoclaw#2648.
"""
from __future__ import annotations
import sys
def _latest_session_id() -> str | None:
"""Return the most recently active session id, or None.
Used when the user runs ``hermes trace upload`` without an explicit id
(the common case from the shell — they mean "the last thing I did").
"""
try:
from hermes_state import SessionDB
db = SessionDB()
sessions = db.list_sessions_rich(limit=1, order_by_last_active=True)
if sessions:
return sessions[0].get("id")
except Exception:
pass
return None
def run_trace(args) -> None:
"""Dispatch ``hermes trace <subcommand>``."""
sub = getattr(args, "trace_command", None)
if sub in ("upload", "up"):
_run_upload(args)
return
# No/unknown subcommand → brief usage.
print("Usage: hermes trace upload [SESSION_ID] [--public] [--no-redact]")
print("Upload a session transcript to your private Hugging Face traces dataset,")
print("viewable in the HF Agent Trace Viewer (https://huggingface.co/docs/hub/agent-traces).")
def _run_upload(args) -> None:
from hermes_cli.env_loader import load_hermes_dotenv
from hermes_cli.config import get_env_path, get_project_root
# Load .env so HF_TOKEN is visible even outside a running session.
env_path = get_env_path()
try:
load_hermes_dotenv(
hermes_home=env_path.parent,
project_env=get_project_root() / ".env",
)
except Exception:
pass
from agent.trace_upload import upload_session_trace
session_id = getattr(args, "session_id", None) or _latest_session_id()
if not session_id:
print("No session found to upload. Pass a SESSION_ID explicitly.", file=sys.stderr)
sys.exit(1)
status = upload_session_trace(
session_id,
cwd="",
redact=not getattr(args, "no_redact", False),
private=not getattr(args, "public", False),
)
print(status)