feat: add prompt-first batches and pausable task guidance

This commit is contained in:
chenmingxuan committed 2026-09-23 22:59:48 +08:00
1 parent cec9898e4c
commit 057f0c3050
44 files changed
+1080 -191

No files matched your search

+68 -10
View File
@@ -540,6 +540,7 @@ class Agent:
last_state: State | None = None
last_state_snapshot: dict | None = None
output = None
task_control = None
effective_mode = getattr(self._config, "concurrency_mode", "per_device")
effective_max = getattr(self._config, "max_concurrency", None)
sess_id = (
@@ -599,6 +600,11 @@ class Agent:
# publish a new active session while the current task is still
# finishing.
self._prepare_tracing(task=task, context=context)
if device_lock is not None and os.environ.get("ARTEMIS_TASK_WORKER") == "1":
from artemis.runtime.task_control import TaskControl
task_control = TaskControl(str(sess_id), device_lock)
context.task_control = task_control
self._prepare_output_files(task=task)
if os.environ.get("ARTEMIS_CLOUD_MODE") != "1":
if self._ui_adb_client is not None:
@@ -612,16 +618,46 @@ class Agent:
await self._prepare_app_lock(task=task, context=context)
async with context:
recording_started = False
if self._config.video_recording_tools_enabled:
recording_parts = 1
controller = get_controller(context)
output_dir = None
if context.execution_setup and context.execution_setup.traces_path:
output_dir = (
self._tmp_traces_dir / context.execution_setup.trace_name
).resolve()
async def pause_capture():
nonlocal recording_started
if recording_started:
try:
await controller.stop_video_recording()
finally:
recording_started = False
from artemis.tools.command_tool import shutdown_adb_background_tasks
await shutdown_adb_background_tasks(context)
async def resume_capture():
nonlocal recording_started, recording_parts
if not (
self._config.video_recording_tools_enabled
or self._config.record_video_enabled
):
return
recording_parts += 1
target = (
output_dir / f"resume_{recording_parts:04d}" if output_dir else None
)
result = await controller.start_video_recording(output_dir=target)
recording_started = bool(result and result.success)
context.on_task_pause = pause_capture
context.on_task_resume = resume_capture
if (
self._config.video_recording_tools_enabled
or self._config.record_video_enabled
):
try:
controller = get_controller(context)
output_dir = None
if context.execution_setup and context.execution_setup.traces_path:
output_dir = (
self._tmp_traces_dir / context.execution_setup.trace_name
).resolve()
logger.info(f"[{task_name}] Starting automated screen recording...")
start_res = await controller.start_video_recording(
output_dir=output_dir
@@ -840,6 +876,25 @@ class Agent:
except Exception as e:
logger.warning(f"[{task_name}] Failed to stop background ADB tasks: {e}")
try:
if (
self._config.video_recording_tools_enabled
and not self._config.record_video_enabled
):
# Video analysis used a temporary capture during execution.
# Keep no recording after the final model/report step.
trace_dir = (self._tmp_traces_dir / task_name).resolve()
root = self._tmp_traces_dir.resolve()
if trace_dir.is_relative_to(root) and trace_dir.is_dir():
for recording in trace_dir.rglob("*"):
if recording.is_file() and (
recording.suffix.lower() in {".mkv", ".mp4", ".webm"}
or recording.name == "recording.json"
):
recording.unlink(missing_ok=True)
if context.data_engine and context.data_engine.current_session_id:
context.data_engine.storage.discard_session_recordings(
str(context.data_engine.current_session_id)
)
await self._finalize_tracing_safely(task=task, context=context)
finally:
if os.environ.get("ARTEMIS_CLOUD_MODE") != "1":
@@ -847,7 +902,9 @@ class Agent:
if self._ui_adb_client is not None:
await asyncio.to_thread(self._ui_adb_client.disconnect)
finally:
if device_lock is not None:
if task_control is not None:
await asyncio.to_thread(task_control.release)
elif device_lock is not None:
await asyncio.to_thread(device_lock.release)
async with self._task_lock:
@@ -1074,6 +1131,7 @@ class Agent:
if task.request.record_trace
else False,
video_recording_tools_enabled=self._config.video_recording_tools_enabled,
record_video_enabled=self._config.record_video_enabled,
disable_checker=self._config.disable_checker,
disable_midway_checks=self._config.disable_midway_checks,
disable_final_check=self._config.disable_final_check,
@@ -609,6 +609,7 @@ class AgentConfigBuilder:
servers=self._servers,
graph_config_callbacks=self._graph_config_callbacks,
video_recording_tools_enabled=self._video_recording_tools_enabled,
record_video_enabled=settings.ARTEMIS_RECORDING_ENABLED,
force_web_accessibility=self._force_web_accessibility,
disable_checker=self._disable_checker,
disable_midway_checks=self._disable_midway_checks,
+2
View File
@@ -29,6 +29,7 @@ from artemis.config import (
from artemis.context import DevicePlatform
from artemis.sdk.types.task import AgentProfile, TaskRequestCommon
from artemis.utils.video import detect_video_tools_enabled
from artemis.config.settings import settings
from pydantic import BaseModel, Field
@@ -113,6 +114,7 @@ class AgentConfig(BaseModel):
servers: ServerConfig
graph_config_callbacks: Callbacks = None
video_recording_tools_enabled: bool = Field(default_factory=detect_video_tools_enabled)
record_video_enabled: bool = Field(default_factory=lambda: settings.ARTEMIS_RECORDING_ENABLED)
force_web_accessibility: bool = False
disable_checker: bool = False
disable_midway_checks: bool = True