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:
1 parent
b584dae80a
commit
83bcfd54d5
52 files changed
+898
-33
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user