feat: add guided exploration and share user-started MCP backend
This commit is contained in:
1 parent
f86db1ced6
commit
ee256ad7ce
144 files changed
+8625
-2075
No files matched your search
@@ -25,16 +25,10 @@ import time
|
||||
from typing import Any
|
||||
import uuid
|
||||
|
||||
try:
|
||||
from admin_console.core.state import state
|
||||
from admin_console.database.repositories.session_repository import session_repo
|
||||
from admin_console.services import worker_process_io
|
||||
from admin_console.services.media_service import media_service
|
||||
except ImportError:
|
||||
from apps.admin_console.core.state import state
|
||||
from apps.admin_console.database.repositories.session_repository import session_repo
|
||||
from apps.admin_console.services import worker_process_io
|
||||
from apps.admin_console.services.media_service import media_service
|
||||
from apps.admin_console.core.state import state
|
||||
from apps.admin_console.database.repositories.session_repository import session_repo
|
||||
from apps.admin_console.services import worker_process_io
|
||||
from apps.admin_console.services.media_service import media_service
|
||||
|
||||
from artemis.config import (
|
||||
PAUSE_FILE,
|
||||
@@ -585,6 +579,12 @@ class TaskQueueService:
|
||||
env["ARTEMIS_SESSION_ID"] = str(sess_id)
|
||||
env["ARTEMIS_TASK_INGRESS"] = str(task_item.get("ingress", "frontend"))
|
||||
env["ARTEMIS_TASK_WORKER"] = "1"
|
||||
from artemis.exploration.store import explorations
|
||||
|
||||
exploration_run = explorations.run(str(sess_id)) if sess_id else None
|
||||
env.pop("ARTEMIS_EXPLORATION_ID", None)
|
||||
if exploration_run and exploration_run["kind"] == "exploration":
|
||||
env["ARTEMIS_EXPLORATION_ID"] = exploration_run["exploration_id"]
|
||||
overrides = task_item.get("runtime_overrides") or {}
|
||||
if overrides.get("recording") is not None:
|
||||
env["ARTEMIS_TASK_RECORDING_CONFIG"] = json.dumps(overrides["recording"])
|
||||
@@ -669,6 +669,11 @@ class TaskQueueService:
|
||||
batch = store.get("batch", job["batch_id"]) if job and job.get("batch_id") else None
|
||||
limit = task_timeout(task_item, job, batch)
|
||||
budget = ExecutionBudget(limit)
|
||||
from artemis.exploration.store import explorations
|
||||
|
||||
exploration_run = explorations.run(sid)
|
||||
is_exploration = bool(exploration_run and exploration_run["kind"] == "exploration")
|
||||
exploration_finalized = False
|
||||
cleanup_limit = (task_item.get("runtime_overrides") or {}).get(
|
||||
"worker_cleanup_timeout_seconds"
|
||||
) or settings.ARTEMIS_WORKER_CLEANUP_TIMEOUT_SECONDS
|
||||
@@ -681,6 +686,9 @@ class TaskQueueService:
|
||||
return waiter.result()
|
||||
outcome = read_worker_outcome(sid)
|
||||
if outcome:
|
||||
if exploration_run and not exploration_finalized:
|
||||
explorations.finish_run(sid, {**outcome, "status": outcome["task_status"]})
|
||||
exploration_finalized = True
|
||||
finalized_at = finalized_at if finalized_at is not None else time.monotonic()
|
||||
if time.monotonic() - finalized_at >= cleanup_limit:
|
||||
logger.warning(
|
||||
@@ -692,6 +700,9 @@ class TaskQueueService:
|
||||
return await waiter
|
||||
continue # Final result is authoritative; only bound resource cleanup now.
|
||||
cls._sync_control_states()
|
||||
if is_exploration:
|
||||
# The worker owns its pausable budget so it survives a UI server restart.
|
||||
continue
|
||||
run = state.active_runs.get(run_key, {})
|
||||
remaining = budget.update(
|
||||
excluded=bool(run.get("parked")) or read_state(sid).get("status") == "queued"
|
||||
@@ -1077,9 +1088,35 @@ class TaskQueueService:
|
||||
f"[QueueWorker] Could not persist failure status for [{sess_id}]"
|
||||
)
|
||||
finally:
|
||||
await cls._finish_output_forwarder(output_task)
|
||||
# 5. Clean up the finished task and release this run's scheduling slot
|
||||
cls._release_run_slot(sess_id, run_key, proc)
|
||||
try:
|
||||
await cls._finish_output_forwarder(output_task)
|
||||
if sess_id:
|
||||
from artemis.exploration.store import explorations
|
||||
from artemis.runtime.task_result import read_worker_outcome
|
||||
|
||||
exploration_run = explorations.run(str(sess_id))
|
||||
if exploration_run and exploration_run.get("outcome") is None:
|
||||
from artemis.runtime.case_result import read_case_result
|
||||
|
||||
outcome = read_worker_outcome(str(sess_id)) or {}
|
||||
session = session_repo.get_session_by_id(str(sess_id)) or {}
|
||||
status = (
|
||||
outcome.get("task_status") or session.get("status") or "interrupted"
|
||||
)
|
||||
explorations.finish_run(
|
||||
str(sess_id),
|
||||
{
|
||||
**outcome,
|
||||
"status": status,
|
||||
"test_result": outcome.get("test_result")
|
||||
or read_case_result(str(sess_id), status),
|
||||
},
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Cannot finalize exploration metadata for %s", sess_id)
|
||||
finally:
|
||||
# Metadata/storage failure must never leak a scheduling slot.
|
||||
cls._release_run_slot(sess_id, run_key, proc)
|
||||
|
||||
@classmethod
|
||||
def _find_duplicate_submission(
|
||||
|
||||
Reference in new issue
Block a user