feat: release 2.1.0 with optional Flash final AI review

Default Flash final review to off and persist the setting across the UI,
MCP, SDK and queued tasks. Keep execution separate from test verdicts.

Bundle UI fonts and licenses to remove Google Fonts from startup builds.
Align backend/frontend versions and document installation and upgrades.
This commit is contained in:
chenmingxuan committed 2026-10-23 12:36:56 +08:00
1 parent b584dae80a
commit 83bcfd54d5
52 files changed
+898 -33

No files matched your search

+5 -1
View File
@@ -9,7 +9,11 @@ from artemis.runtime.case_result import read_case_result
def reviewed_result(
session_id: str, ai_result: dict | None, storage: AutomationStore
) -> dict | None:
original = {**ai_result, "source": "ai"} if ai_result else None
original = (
{**ai_result, "source": "system" if ai_result.get("verification_skipped") else "ai"}
if ai_result
else None
)
record = storage.get("case_review", session_id)
reviews = (record or {}).get("reviews") or []
if not reviews:
@@ -35,6 +35,9 @@ def execution_config(item: dict) -> dict:
options["recording"] = {**options["recording"], **(overrides.get("recording") or {})}
options.update({k: v for k, v in overrides.items() if k != "recording" and v is not None})
return {
"flash_final_check_enabled": agent.flash.final_check_enabled
if profile == "flash"
else None,
"runtime_overrides": TaskOptions.model_validate(options).model_dump(exclude_none=True),
"expected_output": item.get("expected_output"),
"enable_outputter": item.get("enable_outputter")
@@ -177,6 +177,9 @@ class CapabilitySettings(BaseModel):
recording_enabled: bool = False
recording: dict = Field(default_factory=dict)
outputter_enabled: bool = True
flash_final_check_enabled: bool = Field(
default_factory=lambda: load_agent_config().flash.final_check_enabled
)
step_summarizer_enabled: bool = True
screenshot_limit_enabled: bool = True
screenshot_max_long_edge: int = 2048
@@ -207,6 +210,7 @@ def get_capability_settings() -> CapabilitySettings:
recording_enabled=settings.ARTEMIS_RECORDING_ENABLED,
recording=load_agent_config().recording.model_dump(),
outputter_enabled=settings.ARTEMIS_OUTPUTTER_ENABLED,
flash_final_check_enabled=load_agent_config().flash.final_check_enabled,
step_summarizer_enabled=settings.ARTEMIS_STEP_SUMMARIZER_ENABLED,
screenshot_limit_enabled=screenshot.enabled,
screenshot_max_long_edge=screenshot.max_long_edge,
@@ -227,6 +231,7 @@ def save_capability_settings(update: CapabilitySettings) -> CapabilitySettings:
"ARTEMIS_VIDEO_ENABLED": update.video_enabled,
"ARTEMIS_RECORDING_ENABLED": update.recording_enabled,
"ARTEMIS_OUTPUTTER_ENABLED": update.outputter_enabled,
"ARTEMIS_FLASH_FINAL_CHECK_ENABLED": update.flash_final_check_enabled,
"ARTEMIS_STEP_SUMMARIZER_ENABLED": update.step_summarizer_enabled,
"ARTEMIS_SCREENSHOT_LIMIT_ENABLED": update.screenshot_limit_enabled,
"ARTEMIS_TASK_TIMEOUT_SECONDS": update.task_timeout_seconds,
+7 -1
View File
@@ -73,6 +73,8 @@ def text(value) -> str:
def verdict(outcome: dict | None) -> str:
result = (outcome or {}).get("test_result")
if isinstance(result, dict) and result.get("status") in RESULT_LABELS:
if result["status"] == "inconclusive" and result.get("verification_skipped"):
return "未做 AI 判定"
label = RESULT_LABELS[result["status"]]
if result.get("source"):
label += "(人工确认)" if result["source"] == "human" else "(AI确认)"
@@ -273,7 +275,11 @@ def metadata(report: dict) -> list[tuple]:
("验证结论", report["verdict"]),
("人工复验时间", time_text((report.get("test_result") or {}).get("reviewed_at"))),
(
"原 AI 结论",
"原始结果"
if ((report.get("test_result") or {}).get("ai_result") or {}).get(
"verification_skipped"
)
else "原 AI 结论",
verdict({"test_result": (report.get("test_result") or {}).get("ai_result")})
if (report.get("test_result") or {}).get("source") == "human"
else "—",
@@ -579,6 +579,13 @@ class TaskQueueService:
env["ARTEMIS_SESSION_ID"] = str(sess_id)
env["ARTEMIS_TASK_INGRESS"] = str(task_item.get("ingress", "frontend"))
env["ARTEMIS_TASK_WORKER"] = "1"
# Capture the global Flash choice at launch, including saved favorites.
# It is metadata in the snapshot, never a favorite's runtime override.
flash_final_check = (task_item.get("execution_config") or {}).get(
"flash_final_check_enabled"
)
if profile == "flash" and flash_final_check is not None:
env["ARTEMIS_FLASH_FINAL_CHECK_ENABLED"] = str(flash_final_check).lower()
from artemis.exploration.store import explorations
exploration_run = explorations.run(str(sess_id)) if sess_id else None