mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-11 03:31:55 +00:00
Follow latest child session on dashboard resume
This commit is contained in:
parent
e9685a5cf7
commit
b12a5a72b0
3 changed files with 134 additions and 3 deletions
|
|
@ -2173,6 +2173,83 @@ async def cancel_oauth_session(session_id: str, request: Request):
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
def _session_latest_descendant(session_id: str):
|
||||
"""Resolve a session id to the newest child leaf session.
|
||||
|
||||
/model may create child sessions. Dashboard refresh should continue the
|
||||
newest child instead of reopening the old parent.
|
||||
"""
|
||||
from hermes_state import SessionDB
|
||||
|
||||
def row_get(row, key, index):
|
||||
if isinstance(row, dict):
|
||||
return row.get(key)
|
||||
try:
|
||||
return row[key]
|
||||
except Exception:
|
||||
try:
|
||||
return row[index]
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
db = SessionDB()
|
||||
try:
|
||||
sid = db.resolve_session_id(session_id)
|
||||
if not sid or not db.get_session(sid):
|
||||
return None, []
|
||||
|
||||
conn = (
|
||||
getattr(db, "conn", None)
|
||||
or getattr(db, "_conn", None)
|
||||
or getattr(db, "connection", None)
|
||||
or getattr(db, "_connection", None)
|
||||
)
|
||||
|
||||
rows = []
|
||||
if conn is not None:
|
||||
raw_rows = conn.execute(
|
||||
"SELECT id, parent_session_id, started_at FROM sessions"
|
||||
).fetchall()
|
||||
for row in raw_rows:
|
||||
rows.append({
|
||||
"id": row_get(row, "id", 0),
|
||||
"parent_session_id": row_get(row, "parent_session_id", 1),
|
||||
"started_at": row_get(row, "started_at", 2),
|
||||
})
|
||||
else:
|
||||
rows = db.list_sessions_rich(limit=10000, offset=0)
|
||||
|
||||
children = {}
|
||||
for row in rows:
|
||||
rid = row.get("id")
|
||||
parent = row.get("parent_session_id")
|
||||
if rid and parent:
|
||||
children.setdefault(parent, []).append(row)
|
||||
|
||||
def started(row):
|
||||
try:
|
||||
return float(row.get("started_at") or 0)
|
||||
except Exception:
|
||||
return 0.0
|
||||
|
||||
current = sid
|
||||
path = [sid]
|
||||
seen = {sid}
|
||||
|
||||
while children.get(current):
|
||||
candidates = [r for r in children[current] if r.get("id") not in seen]
|
||||
if not candidates:
|
||||
break
|
||||
candidates.sort(key=started, reverse=True)
|
||||
current = candidates[0]["id"]
|
||||
path.append(current)
|
||||
seen.add(current)
|
||||
|
||||
return current, path
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@app.get("/api/sessions/{session_id}")
|
||||
async def get_session_detail(session_id: str):
|
||||
from hermes_state import SessionDB
|
||||
|
|
@ -2187,6 +2264,19 @@ async def get_session_detail(session_id: str):
|
|||
db.close()
|
||||
|
||||
|
||||
|
||||
@app.get("/api/sessions/{session_id}/latest-descendant")
|
||||
async def get_session_latest_descendant(session_id: str):
|
||||
latest, path = _session_latest_descendant(session_id)
|
||||
if not latest:
|
||||
raise HTTPException(status_code=404, detail="Session not found")
|
||||
return {
|
||||
"requested_session_id": path[0] if path else session_id,
|
||||
"session_id": latest,
|
||||
"path": path,
|
||||
"changed": bool(path and latest != path[0]),
|
||||
}
|
||||
|
||||
@app.get("/api/sessions/{session_id}/messages")
|
||||
async def get_session_messages(session_id: str):
|
||||
from hermes_state import SessionDB
|
||||
|
|
@ -2958,6 +3048,9 @@ def _resolve_chat_argv(
|
|||
env.setdefault("HERMES_TUI_DISABLE_MOUSE", "1")
|
||||
|
||||
if resume:
|
||||
latest_resume, _latest_path = _session_latest_descendant(resume)
|
||||
if latest_resume:
|
||||
resume = latest_resume
|
||||
env["HERMES_TUI_RESUME"] = resume
|
||||
|
||||
if sidecar_url:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue