feat(runtime): capture step evidence in console
Tests / Test passed: 862

This commit is contained in:
2026-07-15 10:12:09 +08:00
parent 8d5b02e37f
commit ccde30e378
20 changed files with 594 additions and 53 deletions
+61 -7
View File
@@ -238,16 +238,37 @@ def test_task_detail_renders_timeline_with_screenshot(tmp_path) -> None:
task_id="task-with-timeline",
scene={"screen": {"width": 10, "height": 20}, "elements": []},
prompt="tap search",
tool_call={"action": "tap", "args": {"x": 1, "y": 2}},
tool_call={
"action": "tap",
"description": "tap search",
"args": {"x": 1, "y": 2},
},
result={"ok": True},
screenshot=PNG_10X20,
before_screenshot=PNG_10X20 + b"before",
after_screenshot=PNG_10X20 + b"after",
ocr_results=[
{
"text": "Search",
"confidence": 0.98,
"bounds": {"x": 1, "y": 2, "width": 3, "height": 4},
}
],
)
body = client.get("/ui/tasks/task-with-timeline").text
expected_data_uri = "data:image/png;base64," + base64.b64encode(PNG_10X20).decode(
"ascii"
)
assert expected_data_uri in body
assert "tap" in body
before_data_uri = "data:image/png;base64," + base64.b64encode(
PNG_10X20 + b"before"
).decode("ascii")
after_data_uri = "data:image/png;base64," + base64.b64encode(
PNG_10X20 + b"after"
).decode("ascii")
assert before_data_uri in body
assert after_data_uri in body
assert "Before action" in body
assert "After action" in body
assert "Operation" in body
assert "OCR results" in body
assert "Search" in body
assert "UI tree" not in body
def test_task_detail_404_for_unknown_task(tmp_path) -> None:
@@ -256,6 +277,39 @@ def test_task_detail_404_for_unknown_task(tmp_path) -> None:
assert response.status_code == 404
def test_task_detail_renders_normalized_ui_tree_result(tmp_path) -> None:
timeline = Timeline(ArtifactStore(tmp_path / "history"))
client, metadata_store = _client(tmp_path, timeline=timeline)
metadata_store.create_task(
Task(id="task-ui-tree", goal="inspect the screen", device_id="iphone-1")
)
timeline.append(
task_id="task-ui-tree",
scene={"screen": {"width": 10, "height": 20}, "elements": []},
prompt="inspect the screen",
tool_call={"action": "get_ui_tree", "description": "inspect UI tree"},
result={
"success": True,
"result": [
{
"id": "ui-000",
"type": "button",
"text": "Search",
"bounds": {"x": 1, "y": 2, "width": 3, "height": 4},
"confidence": 1.0,
}
],
},
)
body = client.get("/ui/tasks/task-ui-tree").text
assert "UI tree" in body
assert "1 normalized nodes" in body
assert "button" in body
assert "Search" in body
def test_config_page_lists_supported_drivers_and_current_max_steps(tmp_path) -> None:
config_store = DeviceConfigStore(tmp_path / "device_config.sqlite3")
config_store.set_setting("max_steps", 5)