feat: add official Codex skill and harden task execution

Install and update artemis-use with task diagnostics and plugin guidance. Preserve cross-device file receipts, review canonical reports, guard stage transitions and reduce small history summaries. Improve exploration lifecycle, request recovery and browser live connections.
This commit is contained in:
chenmingxuan committed 2026-10-18 14:18:37 +08:00
1 parent 2328a4df0c
commit e1ea099592
128 files changed
+4944 -700

No files matched your search

+53 -20
View File
@@ -267,14 +267,15 @@ def mobile_run_task(
verification_level: str | None = None,
explorer_mode: str | None = None,
runtime_overrides: dict[str, Any] | None = None,
request_id: str | None = None,
) -> dict[str, Any]:
"""Starts an autonomous mobile UI automation subagent on a connected Android device.
"""Submit a Flash/Pro Android, computer or mixed task to the user-started ARTEMIS service.
Delegates a mobile workflow to a background agent. Non-blocking: returns
immediately with `trace_id` (for `mobile_manage_task` / `mobile_inspect_trace`),
`device_serial`, `stdout_log`/`stderr_log` paths, and `notes_dir` (Pro only).
On completion (success or failure) a Reactive Wakeup notifies you — but only
when `conversation_id` was provided; without it, rely on your fallback timer.
Completion notifications depend on the caller's configured notification backend;
conversation_id alone does not guarantee the agent client receives a wakeup.
### Model selection (routing)
- **Flash** (default, preferred): simple, deterministic tasks with a clear
@@ -291,23 +292,25 @@ def mobile_run_task(
checkpoints, multi-step planning, or detailed written output (via notes
and `expected_output_desc`).
Timing is not precise: the agent's own inference adds ~5 s per step (Flash)
or ~30 s per turn (Pro) on top of any requested waits — account for this
when the task involves waiting. For recurring workflows, run once to
discover the path, then author a deterministic script instead of
re-delegating.
For interactive case design use mobile_exploration: user guidance, demonstration
analysis and reusable case generation. It has independent model settings.
Inference time varies by model, network and device; do not subtract a fixed
per-step estimate from required waits. Deterministic test code needs explicit
timing and state-based waits verified against the real application.
### Follow-up protocol (CRITICAL)
1. **Fallback timer**: you MUST set a background timer and check the task
status via `mobile_manage_task` at least once every 1 minute — mobile
tasks can stall silently, so never rely on the completion wakeup alone.
2. **Post-task inspection**: after completion, inspect the execution logs
to verify success (`stderr_log` carries critical failures and Python
tracebacks — essential for debugging).
3. **Pro notes**: for Pro runs, read `notes_dir` to extract the results and
plans the subagent recorded.
### Follow-up
1. Poll mobile_manage_task at reasonable intervals (usually 30–60 seconds)
while following a task; do not assume an unconfigured background notification.
2. Read test_result and view_report after completion. Inspect relevant request,
log or step evidence for failures and unexplained waits.
3. Read Pro notes when its plan or detailed output is relevant to the user.
Reuse request_id for retries of the same submission; lookup with
mobile_manage_task(action="lookup", request_id=...). Never repeat a task
with a fresh ID merely because its admission reply was lost.
Args:
request_id: Stable caller-generated ID (letters, numbers, _ or -, up to 100).
task_desc: Clear, self-contained task description with all context,
exact UI actions, and termination conditions (execution is one-shot).
For Pro, may also specify what the subagent must record in its notes.
@@ -351,6 +354,39 @@ def mobile_run_task(
fps, h264_kbps, h265_kbps; it does not enable recording on its own.
Unknown fields and credentials are rejected.
"""
parameters = dict(
task_desc=task_desc,
conversation_id=conversation_id,
model=model,
locked_app_package=locked_app_package,
app_path=app_path,
expected_output_desc=expected_output_desc,
device_serial=device_serial,
verification_level=verification_level,
explorer_mode=explorer_mode,
runtime_overrides=runtime_overrides,
)
if request_id is not None:
from mcp_server.task_requests import run_once
return run_once(request_id, parameters, lambda sid: _run_task(trace_id=sid, **parameters))
return _run_task(trace_id=str(uuid.uuid4()), **parameters)
def _run_task(
*,
trace_id: str,
task_desc: str,
conversation_id: str | None,
model: str,
locked_app_package: str | None,
app_path: str | None,
expected_output_desc: str | None,
device_serial: str | None,
verification_level: str | None,
explorer_mode: str | None,
runtime_overrides: dict[str, Any] | None,
) -> dict[str, Any]:
if runtime_overrides:
from apps.admin_console.services.task_import import TaskOptions
@@ -370,9 +406,6 @@ def mobile_run_task(
# plain tool error rather than a failed trace on disk.
verification_level, explorer_mode = _normalize_pro_tuning(verification_level, explorer_mode)
# 1. Generate a unique trace_id
trace_id = str(uuid.uuid4())
# 2. Initialize the trace store directory and status.json
trace_store.init_trace(
trace_id=trace_id,