feat: enhance daemon dispatching, device readiness fallback, and live streaming UI

- Admin Console & Task Queue: add cancellation, session startup progress endpoints, and support ingress metadata
- Diagnostics & Runtime: enhance ADB probe to prefer unlocked devices and synchronize with readiness engine
- MCP Server: dispatch tasks through Artemis Daemon scheduler with fallback to standalone runner, improve action overlays
- Showcase UI: improve session auto-selection with pinning support, render startup progress, and refine stream styling
- CLI & Makefile: expose server lifecycle commands (restart, stop, status)
- Configuration: ignore runtime server state file in .gitignore
This commit is contained in:
somew1nd committed 2026-08-26 17:41:23 -07:00
1 parent 57655266cc
commit 8fdecf23d7
33 files changed
+1315 -293

No files matched your search

+12 -3
View File
@@ -90,7 +90,14 @@ class ReadinessEngine:
def get_active_device_serial(self) -> str | None:
"""Get currently selected active device serial."""
return self._active_device_serial
if self._report_cache and self._report_cache.active_device:
if self._report_cache.active_device.is_locked is False:
return self._report_cache.active_device.serial
if self._active_device_serial:
return self._active_device_serial
if self._report_cache and self._report_cache.active_device:
return self._report_cache.active_device.serial
return None
async def run_probe(self, probe_id: str) -> ProbeResult | None:
"""Execute a single specific probe by ID."""
@@ -99,9 +106,11 @@ class ReadinessEngine:
return None
return await probe.probe()
async def run_device_submission_probe(self) -> ProbeResult:
async def run_device_submission_probe(
self, target_serial: str | None = None
) -> ProbeResult:
"""Run the bounded device gate used by task submission."""
return await self._adb_probe.probe_submission_readiness()
return await self._adb_probe.probe_submission_readiness(target_serial=target_serial)
def invalidate_cache(self) -> None:
"""Invalidate the UI readiness snapshot after an explicit configuration change."""
+45 -7
View File
@@ -358,7 +358,9 @@ class AdbDeviceProbe(BaseProbe):
logger.debug(f"Failed submission-time ADB device check: {exc}")
return None
async def probe_submission_readiness(self) -> ProbeResult:
async def probe_submission_readiness(
self, target_serial: str | None = None
) -> ProbeResult:
"""Run the minimal fail-safe device check required before enqueueing.
The full diagnostics probe enriches device metadata, scans packages,
@@ -416,16 +418,42 @@ class AdbDeviceProbe(BaseProbe):
},
)
serial = (
self._target_serial
preferred = (
target_serial
if target_serial and target_serial in ready_serials
else self._target_serial
if self._target_serial in ready_serials
else ready_serials[0]
)
serial = preferred
is_locked = await self._get_confirmed_device_lock_state(
adb_path,
serial,
timeout_seconds=1.0,
)
# If preferred device is locked or unknown, check remaining ready devices for an unlocked one
if is_locked is not False and len(ready_serials) > 1:
for candidate in ready_serials:
if candidate == preferred:
continue
candidate_locked = await self._get_confirmed_device_lock_state(
adb_path,
candidate,
timeout_seconds=1.0,
)
if candidate_locked is False:
logger.info(
f"Device {preferred} is not ready/unlocked ({is_locked}); "
f"switching to unlocked ready device {candidate}"
)
serial = candidate
is_locked = False
break
elif candidate_locked is None and is_locked is True:
serial = candidate
is_locked = None
summary = (
"Device Locked"
if is_locked is True
@@ -796,11 +824,21 @@ class AdbDeviceProbe(BaseProbe):
)
# 4. Ready device available
active_dev = ready_devices[0]
preferred_dev = None
if self._target_serial:
matched = next((d for d in ready_devices if d.serial == self._target_serial), None)
if matched:
active_dev = matched
preferred_dev = next((d for d in ready_devices if d.serial == self._target_serial), None)
if preferred_dev and preferred_dev.is_locked is False:
active_dev = preferred_dev
else:
# Prefer a confirmed unlocked ready device
unlocked_dev = next((d for d in ready_devices if d.is_locked is False), None)
if unlocked_dev:
active_dev = unlocked_dev
else:
# If no confirmed unlocked device, prefer undetermined lock state over confirmed locked
unknown_dev = next((d for d in ready_devices if d.is_locked is None), None)
active_dev = preferred_dev or unknown_dev or ready_devices[0]
display_name = active_dev.model or active_dev.serial
if active_dev.screen_resolution: