Phase 2: Chat History for Agent Tab
Backend: _get_chat_history() reads JSONL sessions. API: GET /api/agents/{id}/chat-history. Frontend: Chat History tab shows session list with title, model, message count. Click to open session in chat panel.
This commit is contained in:
@@ -514,3 +514,86 @@ def get_agent_errors(agent_id: str, limit: int = 20) -> dict:
|
||||
"agent_id": agent_id,
|
||||
"errors": errors,
|
||||
}
|
||||
|
||||
|
||||
# ── Chat History ──────────────────────────────────────────────────────────────
|
||||
|
||||
def _get_chat_history(agent_id: str, limit: int = 20) -> list[dict]:
|
||||
"""
|
||||
Read chat sessions from JSONL files and return history for a specific agent.
|
||||
Sessions are sorted newest-first.
|
||||
Returns list of {session_id, title, message_count, created_at, last_message_at, model}.
|
||||
"""
|
||||
sessions_dir = _HERMES_DIR / "sessions"
|
||||
if not sessions_dir.exists():
|
||||
return []
|
||||
|
||||
sessions = sorted(sessions_dir.glob("*.jsonl"), key=lambda p: p.stat().st_mtime, reverse=True)
|
||||
history = []
|
||||
|
||||
for session_file in sessions[:limit * 2]: # overscan
|
||||
if len(history) >= limit:
|
||||
break
|
||||
try:
|
||||
with open(session_file) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
if not lines:
|
||||
continue
|
||||
|
||||
# First line has metadata
|
||||
metadata = json.loads(lines[0])
|
||||
created_at = metadata.get("timestamp", "")
|
||||
model = metadata.get("model", "unknown")
|
||||
|
||||
# Count messages
|
||||
message_count = sum(1 for l in lines if l.strip())
|
||||
|
||||
# Title = first user message preview
|
||||
title = "Chat"
|
||||
for line in lines[1:]:
|
||||
if line.strip():
|
||||
try:
|
||||
msg = json.loads(line)
|
||||
if msg.get("role") == "user":
|
||||
content = str(msg.get("content", ""))[:80]
|
||||
title = content if content else "Chat"
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Last message timestamp
|
||||
last_msg = None
|
||||
for line in reversed(lines):
|
||||
if line.strip():
|
||||
try:
|
||||
last_msg = json.loads(line).get("timestamp", created_at)
|
||||
break
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
session_id = session_file.stem # filename without .jsonl
|
||||
|
||||
history.append({
|
||||
"session_id": session_id,
|
||||
"title": title,
|
||||
"message_count": message_count,
|
||||
"created_at": created_at,
|
||||
"last_message_at": last_msg or created_at,
|
||||
"model": model,
|
||||
})
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return history[:limit]
|
||||
|
||||
|
||||
def get_agent_chat_history(agent_id: str, limit: int = 20) -> dict:
|
||||
"""API: GET /api/agents/{id}/chat-history — return chat history for agent."""
|
||||
if agent_id not in TIER2_AGENTS and agent_id != "rose":
|
||||
return {"error": f"Unknown agent: {agent_id}"}
|
||||
history = _get_chat_history(agent_id, limit)
|
||||
return {
|
||||
"agent_id": agent_id,
|
||||
"sessions": history,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user