feat: prepare 2.2.0 with UI and execution fixes

Add dark theme, richer Markdown and readable plugin results.
Improve Android input evidence, response integrity and diagnostics.
Unify lifecycle, guidance receipts and evidence sources across clients.
Keep direct action dispatch without an added AI quota approval layer.
Align version metadata at 2.2.0 and bundle Helper 1.2.2.

Validation: 3063 backend tests before the version bump; 44 after.
Frontend: 317 tests and production build passed.
This commit is contained in:
chenmingxuan committed 2026-10-26 00:44:13 +08:00
1 parent 83bcfd54d5
commit fac4ccb760
146 files changed
+5689 -2033

No files matched your search

+9 -33
View File
@@ -128,33 +128,14 @@ async def _run_precondition_gate(
async def _attempt_local_execution(
node, session, action_item: dict, action_name, attempts_log: list, *, max_local_retries: int
node, session, action_item: dict, action_name, attempts_log: list
) -> tuple[bool, str]:
"""Executes the action locally with a short retry loop."""
success = False
error_msg = ""
for attempt in range(max_local_retries):
try:
exec_success, exec_error = await node._exec_action(session, action_item)
except Exception as e:
exec_success = False
exec_error = str(e)
# No effect polling: "dispatched" only says the device accepted the
# command; whether it had the intended effect is the Operator's call.
if exec_success:
success = True
error_msg = ""
attempts_log.append("Dispatched")
break
else:
success = False
error_msg = exec_error
attempts_log.append(error_msg)
if attempt < max_local_retries - 1:
await asyncio.sleep(0.5)
"""Dispatch once; a device error is not evidence that no input occurred."""
try:
success, error_msg = await node._exec_action(session, action_item)
except Exception as exc:
success, error_msg = False, str(exc)
attempts_log.append("Dispatched" if success else error_msg)
return success, error_msg
@@ -232,19 +213,14 @@ async def _process_action(
attempts_log.append(outcome.error_msg)
if validation_passed:
# 2. Local execution: a vetted action gets a short retry loop, a burst
# member fires exactly once (retries would break the burst's timing).
if burst:
max_local_retries = 1
else:
max_local_retries = 1 if action_name == "launch_app" else 2
# 2. Send one input. An uncertain transport/device outcome must not
# trigger a second physical dispatch, in either tier.
outcome.success, outcome.error_msg = await _attempt_local_execution(
node,
session,
action_item,
action_name,
attempts_log,
max_local_retries=max_local_retries,
)
if not outcome.success: