feat(cli): /timestamps command + timestamps in /history (#50506)

display.timestamps already drove the [HH:MM] suffix on live submitted and
streamed message labels, but there was no runtime command to toggle it and
/history ignored the setting entirely. Add /timestamps [on|off|status]
(alias /ts) and render [HH:MM] in /history for turns that carry a stored
unix timestamp (resumed sessions). Live unsaved turns without a stored time
are never given a fabricated one. Uses the existing sanctioned non-wire
'timestamp' message key (stripped before the API call in chat_completions),
so message-alternation and prompt-cache invariants are untouched.
This commit is contained in:
Teknium 2026-06-21 22:44:25 -07:00 committed by GitHub
parent b9b4756ab4
commit 5ff11a689b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 171 additions and 2 deletions

22
cli.py
View file

@ -6216,6 +6216,22 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin):
preview_limit = 400
visible_index = 0
hidden_tool_messages = 0
show_ts = bool(getattr(self, "show_timestamps", False))
def _ts_suffix(message: dict) -> str:
# Messages restored from SessionDB carry a unix `timestamp`; live
# unsaved turns may not. Only annotate when both the toggle is on
# and the turn actually has a stored time — never fabricate one.
if not show_ts:
return ""
ts = message.get("timestamp")
if not ts:
return ""
try:
from datetime import datetime
return f" [{datetime.fromtimestamp(float(ts)).strftime('%H:%M')}]"
except (ValueError, OSError, TypeError):
return ""
def flush_tool_summary():
nonlocal hidden_tool_messages
@ -6249,13 +6265,13 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin):
content_text = "" if content is None else str(content)
if role == "user":
print(f"\n [You #{visible_index}]")
print(f"\n [You #{visible_index}]{_ts_suffix(msg)}")
print(
f" {content_text[:preview_limit]}{'...' if len(content_text) > preview_limit else ''}"
)
continue
print(f"\n [Hermes #{visible_index}]")
print(f"\n [Hermes #{visible_index}]{_ts_suffix(msg)}")
tool_calls = msg.get("tool_calls") or []
if content_text:
preview = content_text[:preview_limit]
@ -7978,6 +7994,8 @@ class HermesCLI(CLIAgentSetupMixin, CLICommandsMixin):
self._status_bar_visible = not self._status_bar_visible
state = "visible" if self._status_bar_visible else "hidden"
self._console_print(f" Status bar {state}")
elif canonical == "timestamps":
self._handle_timestamps_command(cmd_original)
elif canonical == "verbose":
self._toggle_verbose()
elif canonical == "footer":