feat(host-agent): make execution history authoritative
Tests / Test failed: 2, passed: 830

This commit is contained in:
2026-07-15 11:46:27 +08:00
parent ccde30e378
commit 77d4813bb2
46 changed files with 890 additions and 3132 deletions
@@ -1,7 +1,6 @@
"""Optional supervisor for the two local external processes the Host Agent
depends on for the macOS single-machine real-device workflow: the Appium
server (which gates real ``Driver.connect()``) and the local Runtime API
(used for local inspection).
"""Optional supervisor for Appium in the macOS single-machine real-device
workflow. Appium gates real driver connections; task inspection is provided by
the Host Agent's own console.
Lives in ``host_agent`` because it spawns and monitors host-level processes
alongside the heartbeat/claim loop. Off by default; see ``HostAgentConfig``.
@@ -56,18 +55,6 @@ def probe_appium(host: str, port: int) -> ProbeResult:
return _probe_http(host, port, path="/status")
def probe_runtime(host: str, port: int) -> ProbeResult:
"""Probe the local Runtime API at ``host:port``. Healthy iff ``GET /devices``
returns 200 with a JSON body.
``api.rest.create_app`` does not expose a dedicated ``/health`` endpoint;
``/devices`` is the stable read-only GET that proves the FastAPI app is
mounted and the device manager is reachable. Per design.md Decision 2 this
is the "equivalent existing endpoint" used for the readiness check.
"""
return _probe_http(host, port, path="/devices")
def _probe_http(host: str, port: int, *, path: str) -> ProbeResult:
# Step 1: plain TCP connect — distinguish "nothing listening" (→ spawn)
# from "something is there but wrong" (→ port conflict, skip).
@@ -98,18 +85,6 @@ def appium_argv_factory(host: str, port: int) -> list[str]:
return ["appium", "--address", host, "--port", str(port)]
def runtime_argv_factory(host: str, port: int) -> list[str]:
return [
"uvicorn",
"api.rest:create_app",
"--factory",
"--host",
host,
"--port",
str(port),
]
@dataclass
class SupervisedDependency:
"""Config + mutable runtime state for one supervised external process."""
@@ -190,16 +165,6 @@ class DependencySupervisor:
probe=probe_appium,
)
)
if ha_config.runtime_supervised:
deps.append(
SupervisedDependency(
name="runtime",
host=ha_config.runtime_host,
port=ha_config.runtime_port,
argv_factory=runtime_argv_factory,
probe=probe_runtime,
)
)
return cls(
deps,
max_attempts=ha_config.dependency_restart_max_attempts,