Limit pending restoration to sessions reloaded from storage

This commit is contained in:
Liang Jiaqing committed 2026-10-19 10:40:35 +08:00
1 parent 4f5a928a6e
commit 4e8029f20e
2 files changed
+48 -5

No files matched your search

+12 -5
View File
@@ -246,6 +246,7 @@ class Session:
partial: Optional[dict] = None
status: str = "idle" # idle|running|error|cancelled
agent: Any = None
pending_restore: bool = False # Only records read back from storage await restoration.
thread: Optional[threading.Thread] = None
cancel_requested: bool = False
active_turn_id: str = ""
@@ -463,7 +464,8 @@ class AgentManager:
plan_path=_sanitize_desktop_plan_path(item["id"], item["plan_path"]),
llm_no=item["llm_no"],
first_message=meta["first_message"], first_message_at=meta["first_message_at"],
log_refs=meta["log_refs"], has_content=meta["has_content"])
log_refs=meta["log_refs"], has_content=meta["has_content"],
pending_restore=True)
def _load_sessions(self):
# New format: one file per session under temp/desktop_sessions/.
@@ -762,6 +764,7 @@ class AgentManager:
agent.verbose = True
threading.Thread(target=agent.run, daemon=True, name=f"GA-{sess.id}").start()
sess.agent = agent
sess.pending_restore = False
self._sync_display_cache(sess)
from frontends import hub
hub.connect(agent, f"desktop-{sess.id}",
@@ -965,7 +968,7 @@ class AgentManager:
"title": sess.title,
"cwd": sess.cwd,
"status": sess.status,
"loaded": sess.agent is not None,
"loaded": not sess.pending_restore,
"createdAt": sess.created_at,
"updatedAt": sess.updated_at,
"lastError": sess.last_error,
@@ -1054,7 +1057,10 @@ class AgentManager:
if sess.status == "running":
raise web.HTTPConflict(text=json.dumps({"error": "session is already running"}, ensure_ascii=False), content_type="application/json")
if sess.agent is None and _e2e_control_token() is None:
self.restore_context(sid)
if sess.pending_restore:
self.restore_context(sid)
else:
self.make_agent(sess)
extra = {}
if image_ids:
extra["image_ids"] = image_ids
@@ -1155,7 +1161,8 @@ class AgentManager:
emit_session_state(sess, "idle")
return
if sess.agent is None:
self.restore_context(sess.id)
with self.mutation():
self.make_agent(sess)
agent = sess.agent
from desktop_history import preview
log_path = getattr(agent, "log_path", None)
@@ -1354,7 +1361,7 @@ class AgentManager:
sess = self.sessions.get(sid)
if not sess:
raise web.HTTPNotFound(text=json.dumps({"error": f"session not found: {sid}"}), content_type="application/json")
if sess.agent is not None:
if not sess.pending_restore:
return {"ok": True, "sessionId": sid, "restored": False, "loaded": True}
try:
self.make_agent(sess)
+36
View File
@@ -198,3 +198,39 @@ def test_display_cache_is_rebuildable_and_follows_ga(manager):
sess.agent.all_outputs.clear()
manager._sync_display_cache(sess)
assert sess.messages == []
def test_new_session_is_not_pending_restore_until_bridge_reload(manager, monkeypatch):
sess = manager.create_session()
assert sess.agent is None
assert manager.snapshot(sess)['loaded'] is True
def unexpected(*args, **kwargs):
raise AssertionError('normal session must not enter history restoration')
monkeypatch.setattr(manager, 'make_agent', unexpected)
assert manager.restore_context(sess.id)['restored'] is False
manager.set_session_model(sess.id, 1)
assert manager.snapshot(sess)['loaded'] is True
assert 'pending_restore' not in manager._session_dict(sess)
manager.sessions.clear()
manager._load_sessions()
restored = manager.sessions[sess.id]
assert restored.agent is None
assert manager.snapshot(restored)['loaded'] is False
def test_new_prompt_initializes_ga_without_restore_path(manager, monkeypatch):
monkeypatch.setattr(sys.modules['plan_state'], 'sync_plan_path_from_text', lambda *a: None, raising=False)
sess = manager.create_session()
monkeypatch.setattr(manager, 'ensure_ga_import_path', lambda: Path(manager.ga_root))
monkeypatch.setitem(sys.modules, 'agentmain', _make_stub('agentmain', {'GenericAgent': FakeAgent}))
monkeypatch.setattr(hub, 'connect', lambda *a, **kw: None)
def unexpected(*args, **kwargs):
raise AssertionError('new prompt must not enter history restoration')
monkeypatch.setattr(manager, 'restore_context', unexpected)
result = manager.submit_prompt(sess.id, 'hello')
assert result['accepted']
sess.thread.join(timeout=3)
assert not sess.thread.is_alive()
assert sess.agent is not None
assert manager.snapshot(sess)['loaded'] is True
assert sess.status == 'idle'