feat: release 2.2.0 with PC-only tests and execution reliability fixes
Unify task scheduling and queue state, fix Android input and observation recovery, preserve screenshot paths, and match final review criteria accurately. Add collapsible copyable results and publish the complete 2.1.0 upgrade notes. Validation: 3189 backend tests, 326 frontend tests, 24 client tests, production build and quality gates.
This commit is contained in:
1 parent
fac4ccb760
commit
be6e8c2abd
79 files changed
+2263
-277
No files matched your search
@@ -59,7 +59,7 @@ from artemis.utils.coordinates import (
|
||||
)
|
||||
from artemis.utils.logger import get_logger
|
||||
from artemis.utils.action_target import element_semantics, observation_anchor
|
||||
from artemis.utils.input_state import verify_input
|
||||
from artemis.utils.input_state import expected_input_state, verify_input
|
||||
from artemis.utils.image_hash import dhash_hex, hamming_distance_hex
|
||||
from artemis.utils.notes import (
|
||||
format_list_notes_failure,
|
||||
@@ -290,12 +290,21 @@ class McpActionExecutor:
|
||||
target_coordinates: list[int] | None = None
|
||||
observation_settled: bool | None = None
|
||||
input_verification: str | None = None
|
||||
expected_input: str | None = None
|
||||
with span:
|
||||
try:
|
||||
session = await self._session_or_start()
|
||||
wire_name, wire_args, finalize, target_semantics = self._translate(
|
||||
raw_name, args, state, index_elements=index_elements
|
||||
)
|
||||
if wire_name == "input_text":
|
||||
expected_input = expected_input_state(
|
||||
wire_args["text"], wire_args["clear_exist"]
|
||||
)
|
||||
elif wire_name == "focus_and_clear_text":
|
||||
expected_input = "empty"
|
||||
if expected_input is not None:
|
||||
input_verification = "unknown"
|
||||
if raw_name in _POINT_TARGET_ACTIONS:
|
||||
# The normalized point the action was sent to: the recorded
|
||||
# coordinates of an index target (the model named an index,
|
||||
@@ -336,12 +345,13 @@ class McpActionExecutor:
|
||||
if obs.hierarchy_ok:
|
||||
state.indexed_points = [el["center"] for el in obs.elements]
|
||||
state.indexed_elements = obs.elements
|
||||
if raw_name == "input_text" and res.ok:
|
||||
input_verification = verify_input(obs.elements, target_semantics)
|
||||
if input_verification != "present":
|
||||
if expected_input is not None and res.ok:
|
||||
if obs.hierarchy_ok:
|
||||
input_verification = verify_input(obs.elements, target_semantics)
|
||||
if input_verification != expected_input:
|
||||
message += (
|
||||
f" Input value verification: {input_verification}. "
|
||||
"Input dispatch is not proof of a filled field; observe and "
|
||||
f" Input value verification: expected {expected_input}, "
|
||||
f"observed {input_verification}. Observe and "
|
||||
"confirm the real value before submitting. Do not repeat input blindly."
|
||||
)
|
||||
if shot_path:
|
||||
@@ -362,7 +372,9 @@ class McpActionExecutor:
|
||||
message = f"{message} Post-action screen is still changing; observe again before concluding."
|
||||
|
||||
status = (
|
||||
"success" if res.ok and input_verification not in {"empty", "unknown"} else "error"
|
||||
"success"
|
||||
if res.ok and (expected_input is None or input_verification == expected_input)
|
||||
else "error"
|
||||
)
|
||||
post_image_name = None
|
||||
if shot_path:
|
||||
|
||||
Reference in new issue
Block a user