fix(state): bound legacy transcript hydration memory
Co-authored-by: Benjamin Brumbaugh <benbrumbaugh@gmail.com>
This commit is contained in:
@@ -752,7 +752,10 @@ def _resume_deferred(ctx: _Resume) -> dict:
|
||||
resume_message_count=int(ctx.found.get("message_count") or 0))
|
||||
if (reused := ctx.claim(sid, record)) is not None:
|
||||
return reused
|
||||
_schedule_resume_hydration(sid, ctx.target, ctx.db, close_db=ctx.owns_db)
|
||||
# Desktop owns the visible transcript through bounded REST pages, not this model-history restore.
|
||||
_schedule_resume_hydration(
|
||||
sid, ctx.target, ctx.db, close_db=ctx.owns_db,
|
||||
model_history_only=source == "desktop" and ctx.omit_messages)
|
||||
ctx.owns_db = False # the hydration worker now owns (and closes) the profile-scoped handle
|
||||
_schedule_session_cap_enforcement()
|
||||
return _resume_response(ctx, sid, record, info=ctx.info(cwd, overrides), messages=[],
|
||||
|
||||
+13
-6
@@ -2575,10 +2575,14 @@ def _schedule_agent_build(sid: str, delay: float = 0.05) -> None:
|
||||
timer.start()
|
||||
|
||||
|
||||
def _load_resume_transcript(db, stored_id: str) -> tuple[list, list, list]:
|
||||
def _load_resume_transcript(db, stored_id: str, *, model_history_only: bool = False) -> tuple[list, list, list]:
|
||||
"""(raw_history, display_history, ancestor_prefix) for a cold resume. The full lineage is materialized
|
||||
only while it fits sessions.max_resume_messages (the transcript is REST-paginated), else the tip alone."""
|
||||
from hermes_state import SessionResumeTooLargeError
|
||||
if model_history_only:
|
||||
raw_history = db.get_messages_as_conversation(
|
||||
stored_id, repair_alternation=True, include_row_ids=True)
|
||||
return raw_history, [], []
|
||||
prefix_fits = True
|
||||
guard = getattr(db, "assert_resume_safe", None)
|
||||
if callable(guard):
|
||||
@@ -2597,7 +2601,8 @@ def _load_resume_transcript(db, stored_id: str) -> tuple[list, list, list]:
|
||||
return raw_history, raw_history, []
|
||||
|
||||
|
||||
def _schedule_resume_hydration(sid: str, stored_id: str, db, *, close_db: bool = False) -> None:
|
||||
def _schedule_resume_hydration(sid: str, stored_id: str, db, *, close_db: bool = False,
|
||||
model_history_only: bool = False) -> None:
|
||||
"""Load a cold resume's transcript off the JSON-RPC response path."""
|
||||
|
||||
def _run() -> None:
|
||||
@@ -2607,22 +2612,24 @@ def _schedule_resume_hydration(sid: str, stored_id: str, db, *, close_db: bool =
|
||||
return
|
||||
_emit("session.resume_progress", sid, {"phase": "history", "status": "loading"})
|
||||
db.reopen_session(stored_id)
|
||||
raw_history, display_history, prefix = _load_resume_transcript(db, stored_id)
|
||||
raw_history, display_history, prefix = _load_resume_transcript(
|
||||
db, stored_id, model_history_only=model_history_only)
|
||||
# Display keeps the full transcript; the model-fed history uses the
|
||||
# same canonicalization as gateway resume and the send path.
|
||||
history = canonicalize_replay_history(raw_history)
|
||||
if _sessions.get(sid) is not session:
|
||||
return
|
||||
with session["history_lock"]:
|
||||
session.update(history=history, display_history_prefix=prefix, resume_hydrating=False,
|
||||
resume_message_count=len(display_history))
|
||||
session.update(history=history, display_history_prefix=prefix, resume_hydrating=False)
|
||||
if not model_history_only:
|
||||
session["resume_message_count"] = len(display_history)
|
||||
# Deferred resumes answered before the transcript existed; cache the derived todo snapshot now.
|
||||
todo_state = _todo_state_from_history(history)
|
||||
if todo_state is not None and session.get("todo_state") is None:
|
||||
session["todo_state"] = todo_state
|
||||
session["resume_history_ready"].set()
|
||||
_emit("session.resume_progress", sid,
|
||||
{"message_count": len(display_history), "phase": "history", "status": "complete"})
|
||||
{"message_count": session["resume_message_count"], "phase": "history", "status": "complete"})
|
||||
_maybe_schedule_auto_continue(sid, session, stored_id)
|
||||
_start_agent_build(sid, session)
|
||||
except Exception as exc:
|
||||
|
||||
Reference in New Issue
Block a user