feat: release 1.1.0 with responsive task control

This commit is contained in:
chenmingxuan committed 2026-09-24 03:31:17 +08:00
1 parent 057f0c3050
commit bfcd828fa8
37 files changed
+1601 -151

No files matched your search

+28 -6
View File
@@ -37,6 +37,7 @@ from artemis.runtime.process_probe import pid_is_alive
from artemis.runtime.task_control import (
add_instruction,
control_dir,
list_instructions,
read_state,
request_pause,
request_resume,
@@ -265,7 +266,7 @@ def mobile_manage_task(
can also steer a subagent that is stuck or off-track, or abort a task.
### Actions
- **'status'**: Returns `trace_id`, `status` ('running'/'task_paused'/
- **'status'**: Returns `trace_id`, `status` ('running'/'pausing'/'task_paused'/
'resuming'/'completed'/'failed'/'cancelled'/'interrupted'), `device_serial` (which phone owns this task in multi-device
setups), `task_desc`, `model`, `elapsed_seconds`, a `test_summary` (when
the run declared verification check items: machine-readable
@@ -274,7 +275,10 @@ def mobile_manage_task(
current turn, latest thought/action — intervene if turns climb without
progress or the thought indicates it is stuck; Pro: the active task plan
— check it still aligns with your goal).
- **'pause'**: Requests a pause after the current action, releasing the device.
- **'pause'**: Requests a pause, returning `pausing` until the runner releases
the device. Pro can interrupt a pending model response or read-only diagnostic;
a device action already in progress must finish safely first. Check status
for `task_paused` before assuming the device is free.
- **'resume'**: Queues a paused task for its device again; optional `instruction`
provides guidance before the next action.
- **'inject_instruction'**: Injects real-time guidance mid-flight when the
@@ -285,6 +289,8 @@ def mobile_manage_task(
`release_loop=True` — this is the only signal that unlocks the
milestone's completion; natural-language "please stop" phrasing in
`instruction` is NOT interpreted as a stop signal.
- **'guidance_history'**: Lists submitted instructions with `pending` or
`consumed` status; a submitted instruction is not proof it was applied.
- **'stop'**: Forcefully terminates the subagent, immediately halting
device interactions and releasing the device. Use when the task is done,
irreparably broken, or running out of control. Prefer
@@ -292,7 +298,8 @@ def mobile_manage_task(
should wind down cleanly instead of being killed.
Args:
action: `"status"`, `"pause"`, `"resume"`, `"inject_instruction"`, or `"stop"`.
action: `"status"`, `"pause"`, `"resume"`, `"inject_instruction"`,
`"guidance_history"`, or `"stop"`.
trace_id: The task's session identifier from `mobile_run_task` or the web UI.
instruction: Guidance string; required for `inject_instruction`
(optional when `release_loop=True`), omit otherwise.
@@ -312,6 +319,12 @@ def mobile_manage_task(
control_status = read_state(trace_id).get("status") if is_alive else None
if control_status in ("task_paused", "resuming") and current_status in ("running", "pending"):
current_status = control_status
elif (
is_alive
and current_status in ("running", "pending")
and (control_dir(trace_id) / "pause.request").exists()
):
current_status = "pausing"
trace_dir = trace_store.get_trace_dir(trace_id)
@@ -524,7 +537,16 @@ def mobile_manage_task(
return response
elif action == "guidance_history":
return {"trace_id": trace_id, "instructions": list_instructions(trace_id)}
elif action == "pause":
if current_status == "pausing":
return {
"trace_id": trace_id,
"status": "pausing",
"message": "Pause is still pending; check status for task_paused.",
}
if current_status not in ("running", "pending", "resuming") or not is_alive:
return {
"trace_id": trace_id,
@@ -535,7 +557,7 @@ def mobile_manage_task(
return {
"trace_id": trace_id,
"status": "pausing",
"message": "Pauses after the current action and releases the device.",
"message": "Pause requested; wait for task_paused and device release.",
}
elif action == "resume":
@@ -555,7 +577,7 @@ def mobile_manage_task(
}
elif action == "stop":
if current_status not in ("running", "pending", "task_paused", "resuming"):
if current_status not in ("running", "pending", "pausing", "task_paused", "resuming"):
return {
"trace_id": trace_id,
"status": current_status,
@@ -650,7 +672,7 @@ def mobile_manage_task(
"message": "Missing required argument 'instruction' for action 'inject_instruction'.",
}
if current_status not in ("running", "pending", "task_paused", "resuming"):
if current_status not in ("running", "pending", "pausing", "task_paused", "resuming"):
return {
"trace_id": trace_id,
"status": current_status,