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:
1 parent
83bcfd54d5
commit
fac4ccb760
146 files changed
+5689
-2033
No files matched your search
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user