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

+32 -10
View File
@@ -16,9 +16,11 @@
import json
import os
from pathlib import Path
import sqlite3
import sys
from typing import Any
from mcp.types import CallToolResult, TextContent
from mcp_server.base import mcp
from mcp_server.utils import env_utils
@@ -72,7 +74,8 @@ async def mobile_inspect_trace(
start with view_report, then inspect only relevant evidence. No export is generated.
- **'view_summary'**: High-level execution summary across all steps.
Pro: hierarchical task plan with per-step status; Flash: paginated execution
chain with each step's reasoning and action.
chain with each step's reasoning and action. Returns summary Markdown plus
steps.items (stored step_id/step_number), total/offset/limit/next_offset.
- **'search'**: Deterministic keyword / step-range lookup over the full
stored history (screen descriptions, exact actions and results,
reasoning, tool calls, notes, on-screen OCR/UI-tree text incl.
@@ -140,7 +143,7 @@ async def mobile_inspect_trace(
pass
try:
conn = sqlite3.connect(db_path)
conn = sqlite3.connect(Path(db_path).resolve().as_uri() + "?mode=ro", uri=True)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
@@ -156,6 +159,9 @@ async def mobile_inspect_trace(
(trace_id, limit, offset),
)
rows = cursor.fetchall()
total_steps = cursor.execute(
"SELECT COUNT(*) FROM steps WHERE session_id = ?", (trace_id,)
).fetchone()[0]
steps = []
for r in rows:
@@ -227,6 +233,28 @@ async def mobile_inspect_trace(
device_info_str = f" | **Device Serial:** `{device_serial}`" if device_serial else ""
def summary_result(markdown):
value = {
"session_id": trace_id,
"device_serial": device_serial,
"summary": markdown[:40000],
"summary_truncated": len(markdown) > 40000,
"steps": {
"items": [
{"step_id": s["step_id"], "step_number": s["step_number"]} for s in steps
],
"total": total_steps,
"offset": offset,
"limit": limit,
"next_offset": offset + limit if offset + limit < total_steps else None,
},
}
footer = f"\n\nPage offset={offset}, limit={limit}, total={total_steps}; next_offset={value['steps']['next_offset']}."
return CallToolResult(
content=[TextContent(type="text", text=value["summary"] + footer)],
structuredContent=value,
)
if is_flash:
summary_lines = [
"# ARTEMIS Flash Execution Summary",
@@ -269,10 +297,7 @@ async def mobile_inspect_trace(
summary_lines.append(f"### Step {s_num} (at {rel_t}, duration {dur_str})")
summary_lines.append(f"- **Thinking / Motivation:** {thought}")
summary_lines.append(f"- **Action Taken:** `{act_str}` -> `{res}`\n")
return (
"\n".join(summary_lines)[:40000]
+ f"\n\nPage offset={offset}, limit={limit}; use offset={offset + limit} for more steps."
)
return summary_result("\n".join(summary_lines))
try:
summary_markdown = build_plan_and_history(
@@ -288,10 +313,7 @@ async def mobile_inspect_trace(
f"**Session ID:** `{trace_id}` | **Model:** Pro{device_info_str}\n\n"
+ summary_markdown
)
return (
summary_markdown[:40000]
+ f"\n\nPage offset={offset}, limit={limit}; use offset={offset + limit} for more steps."
)
return summary_result(summary_markdown)
except Exception as e:
return {
"error": "Formatting error",