fix: improve cross-device evidence and exploration lifecycle

Align Responses cache affinity across execution and summary calls, preserve required checks and evidence uncertainty, and allow safe deletion of inactive explorations while retaining independent reruns.

Validation: backend suite passed except intentional prompt golden drift, then all 17 transcript tests passed after snapshot refresh; 268 frontend tests and production build passed; Ruff, quality ratchet and core type checks passed.
This commit is contained in:
chenmingxuan committed 2026-10-17 19:43:20 +08:00
1 parent f1bb5d02aa
commit 2328a4df0c
32 files changed
+748 -79

No files matched your search

+14
View File
@@ -283,9 +283,18 @@ async def cleanup_history_endpoint():
@router.post("/api/sessions/{session_id}/delete")
async def delete_session_endpoint(session_id: str):
from artemis.exploration.store import ExplorationConflict, explorations
try:
from artemis.data_engine.storage import StorageManager
session_id = str(UUID(session_id))
run = explorations.run(session_id)
if run and run["kind"] == "exploration":
from apps.admin_console.services.exploration_deletion import delete_exploration
deleted = delete_exploration(explorations, run["exploration_id"])
return {"status": "success", "deleted_session_ids": deleted}
storage = StorageManager(DB_PATH, TRACES_PATH)
storage.delete_session(UUID(session_id))
from apps.admin_console.services.automation_store import store
@@ -294,6 +303,11 @@ async def delete_session_endpoint(session_id: str):
return {
"status": "success",
"message": f"Session {session_id} deleted successfully",
"deleted_session_ids": [session_id],
}
except ExplorationConflict as e:
raise HTTPException(status_code=409, detail=str(e)) from e
except (ValueError, KeyError) as e:
raise HTTPException(status_code=400, detail=str(e)) from e
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@@ -0,0 +1,48 @@
"""Delete an inactive conversation while keeping independently executed reruns."""
import shutil
from uuid import UUID
from apps.admin_console.core.state import state
from apps.admin_console.services import report_export
from artemis.data_engine.storage import StorageManager
from artemis.exploration.store import ExplorationConflict, ExplorationStore
from artemis.runtime.process_probe import pid_is_alive
from artemis.runtime.task_control import read_state
def _check_runs(runs: list[dict]) -> None:
queued = {
item.get("session_id")
for item in state.queue_items
if item.get("status") in {"pending", "queued", "running"}
}
for run in runs:
run_id = run["id"]
if (
run_id in state.active_runs
or run_id in queued
or pid_is_alive(read_state(run_id).get("pid"))
):
raise ExplorationConflict("探索工作进程尚未结束,请停止任务并稍后重试删除")
def delete_exploration(repository: ExplorationStore, exploration_id: str) -> list[str]:
runs = repository.begin_delete(exploration_id, _check_runs)
# Validation sessions and batch copies remain ordinary Flash/Pro history.
deleted = [run["id"] for run in runs if run["kind"] == "exploration"]
storage = StorageManager(repository.database.path, report_export.TRACES_PATH)
with report_export.EXPORT_LOCK:
for run_id in deleted:
safe_id = str(UUID(run_id))
storage.delete_session(UUID(safe_id))
repository.database.delete_history(safe_id)
for root in (
report_export.EXPORT_ROOT,
report_export.EXPORT_ROOT.parent / "mcp_exports",
):
folder = (root / "sessions" / safe_id).resolve()
if folder.is_relative_to(root.resolve()) and folder.is_dir():
shutil.rmtree(folder)
repository.finish_delete(exploration_id)
return deleted