feat: enable remote SDK and resilient device orchestration

This commit is contained in:
somew1nd committed 2026-08-30 00:41:07 -07:00
1 parent 3cc711df51
commit ddfa420945
110 files changed
+14450 -12954

No files matched your search

+5 -5
View File
@@ -163,14 +163,14 @@ async def run_part_3():
async def task_3a():
print(f"🚀 [Task 3A - Phone] Global mode starting: Executing on {PHONE_SERIAL}...")
res = await client_phone_g.run("Use manage_app to launch Settings app and report task status completed", profile="flash")
print(f"✅ [Task 3A - Phone] Finished")
print("✅ [Task 3A - Phone] Finished")
return res
async def task_3b():
await asyncio.sleep(0.4)
print(f"🚀 [Task 3B - Emulator] Global mode starting: Targeting {EMULATOR_SERIAL} (should queue due to global limit)...")
res = await client_emu_g.run("Use manage_app to launch Settings app and report task status completed", profile="flash")
print(f"✅ [Task 3B - Emulator] Finished")
print("✅ [Task 3B - Emulator] Finished")
return res
t3a = asyncio.create_task(task_3a())
@@ -199,16 +199,16 @@ async def run_part_4():
client_emu = ArtemisClient(device_serial=EMULATOR_SERIAL, concurrency_mode="per_device")
async def task_4a():
print(f"🚀 [Task 4A - Phone] Started...")
print("🚀 [Task 4A - Phone] Started...")
return await client_phone.run("Use manage_app to launch Settings app and report task status completed", profile="flash")
async def task_4b():
await asyncio.sleep(0.4)
print(f"🚀 [Task 4B - Phone] Started (Queued behind 4A)...")
print("🚀 [Task 4B - Phone] Started (Queued behind 4A)...")
return await client_phone.run("Use manage_app to launch Clock app and report task status completed", profile="flash")
async def task_4c():
print(f"🚀 [Task 4C - Emulator] Started concurrently with 4A...")
print("🚀 [Task 4C - Emulator] Started concurrently with 4A...")
return await client_emu.run("Use manage_app to launch Settings app and report task status completed", profile="flash")
t4a = asyncio.create_task(task_4a())
+10 -2
View File
@@ -72,7 +72,13 @@ def main() -> None:
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("-p", "--port", type=int, default=8000, help="Port to run UI on")
parser.add_argument("-H", "--host", type=str, default="0.0.0.0", help="Host address to bind")
parser.add_argument(
"-H",
"--host",
type=str,
default="127.0.0.1",
help="Host address to bind (loopback by default; use a tunnel for remote access)",
)
parser.add_argument(
"-r",
"--restart",
@@ -181,7 +187,9 @@ def main() -> None:
cmd = []
if has_uv and (ROOT_DIR / "pyproject.toml").exists():
cmd = ["uv", "run", "artemis", "ui", "--port", str(args.port), "--host", args.host]
# Launch via `python -m artemis` (not the `artemis` console-script shim) so the
# long-running server never locks .venv/Scripts/artemis.exe against reinstalls.
cmd = ["uv", "run", "python", "-m", "artemis", "ui", "--port", str(args.port), "--host", args.host]
if args.no_open:
cmd.append("--no-open")
if args.reload:
+4 -2
View File
@@ -159,9 +159,11 @@ if ($installMcp -match "^[Yy]") {
Write-Host ""
# 8. Launch unified Showcase UI & open browser
# Launch via `python -m artemis` (not the `artemis.exe` console-script shim) so the
# long-running server never locks .venv\Scripts\artemis.exe against `uv sync` reinstalls.
Write-Host " [INFO] Launching Artemis Showcase UI & Admin Console..." -ForegroundColor Green
if ($NoOpen) {
uv run artemis ui --port $Port --no-open
uv run python -m artemis ui --port $Port --no-open
} else {
uv run artemis ui --port $Port --open
uv run python -m artemis ui --port $Port --open
}
+5 -5
View File
@@ -156,14 +156,14 @@ async def stage_3_global_concurrency_mode():
async def task_phone_g():
print(f"📱 [Task 3A - Phone] Acquiring global lock on {PHONE_SERIAL}...")
res = await client_phone_global.run("Press HOME key and open Settings", profile="flash")
print(f"✅ [Task 3A - Phone] Finished.")
print("✅ [Task 3A - Phone] Finished.")
return res
async def task_emu_g():
await asyncio.sleep(0.4)
print(f"💻 [Task 3B - Emulator] Requesting run on {EMULATOR_SERIAL} under global mode (Should queue!)...")
res = await client_emu_global.run("Press HOME key and open Settings", profile="flash")
print(f"✅ [Task 3B - Emulator] Finished.")
print("✅ [Task 3B - Emulator] Finished.")
return res
p_task = asyncio.create_task(task_phone_g())
@@ -189,16 +189,16 @@ async def stage_4_mixed_queue_and_parallel():
client_emu = ArtemisClient(device_serial=EMULATOR_SERIAL, concurrency_mode="per_device")
async def task_4a():
print(f"📱 [Task 4A - Phone] Running...")
print("📱 [Task 4A - Phone] Running...")
return await client_phone.run("Press HOME key and open Settings", profile="flash")
async def task_4b():
await asyncio.sleep(0.4)
print(f"📱 [Task 4B - Phone] Queued behind 4A...")
print("📱 [Task 4B - Phone] Queued behind 4A...")
return await client_phone.run("Press HOME key and open Clock", profile="flash")
async def task_4c():
print(f"💻 [Task 4C - Emulator] Running in parallel with 4A...")
print("💻 [Task 4C - Emulator] Running in parallel with 4A...")
return await client_emu.run("Press HOME key and open Settings", profile="flash")
t4a = asyncio.create_task(task_4a())
+1 -1
View File
@@ -152,7 +152,7 @@ async def run_experiment_2_multi_device_parallel(real_serial: str, emu_serial: s
async def run_experiment_3_global_concurrency_serialization(real_serial: str, emu_serial: str):
"""Experiment 3: Global concurrency serialization across devices."""
print_header("[Experiment 3] Global Concurrency Mode Test")
print(f"Mode description: concurrency_mode='global', entire system allows only 1 task across all devices.")
print("Mode description: concurrency_mode='global', entire system allows only 1 task across all devices.")
client_a = ArtemisClient(device_serial=real_serial, default_profile="flash", concurrency_mode="global")
client_b = ArtemisClient(device_serial=emu_serial, default_profile="flash", concurrency_mode="global")