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:
1 parent
83bcfd54d5
commit
fac4ccb760
146 files changed
+5689
-2033
No files matched your search
@@ -14,6 +14,7 @@ from apps.admin_console.services.export_cache import (
|
||||
reusable,
|
||||
)
|
||||
from apps.admin_console.services.request_diagnostics import diagnostics_json
|
||||
from apps.admin_console.services.task_lifecycle import guidance_details
|
||||
|
||||
from docx import Document
|
||||
from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT
|
||||
@@ -166,6 +167,7 @@ def failure_reason(directory: Path, status: str, recorded: str | None) -> str:
|
||||
|
||||
def session_report(session_id: str, db_path=None) -> dict:
|
||||
from apps.admin_console.services.exploration_evidence import exploration_metadata
|
||||
from artemis.data_engine.evidence_sources import recorded_sources
|
||||
|
||||
identifier(session_id)
|
||||
meta = store.job(session_id) or {}
|
||||
@@ -213,6 +215,7 @@ def session_report(session_id: str, db_path=None) -> dict:
|
||||
)
|
||||
return {
|
||||
"id": session_id,
|
||||
**guidance_details(session_id, db_path=repo.db_path),
|
||||
"exploration": exploration_metadata(session_id),
|
||||
"name": execution_title(meta) or session.get("initial_goal", session_id)[:120],
|
||||
"iteration": meta.get("iteration", 1),
|
||||
@@ -225,6 +228,7 @@ def session_report(session_id: str, db_path=None) -> dict:
|
||||
"outcome": outcome,
|
||||
"content": content,
|
||||
"steps": steps,
|
||||
"evidence_sources": recorded_sources(steps),
|
||||
"start": session.get("start_time") or meta.get("started_at"),
|
||||
"end": session.get("end_time") or meta.get("ended_at"),
|
||||
"error": error,
|
||||
@@ -246,6 +250,74 @@ def time_text(value) -> str:
|
||||
)
|
||||
|
||||
|
||||
def lifecycle_text(value: dict) -> str:
|
||||
labels = {
|
||||
"total": "总历时",
|
||||
"queued": "后台排队",
|
||||
"resource_wait": "等待设备/资源",
|
||||
"paused": "暂停与示范",
|
||||
"execution": "执行与整理",
|
||||
"final_review": "最终验收",
|
||||
"report_export": "报告导出",
|
||||
}
|
||||
durations = value.get("durations") or {}
|
||||
return (
|
||||
"\n".join(
|
||||
f"{label}:{round(durations[key], 1)} 秒"
|
||||
if durations.get(key) is not None
|
||||
else f"{label}:未记录"
|
||||
for key, label in labels.items()
|
||||
)
|
||||
+ "\n执行含初始化与报告整理,不代表模型速度。"
|
||||
)
|
||||
|
||||
|
||||
def guidance_text(items: list[dict]) -> str:
|
||||
labels = {
|
||||
"pending": "已接收,等待读取",
|
||||
"reading": "执行器正在读取",
|
||||
"consumed": "执行器已读取",
|
||||
"unapplied": "任务结束,未记录消费",
|
||||
"unconfirmed": "任务结束,读取未确认",
|
||||
}
|
||||
return (
|
||||
"\n".join(
|
||||
f"{item['id']} · {labels.get(item['status'], '状态未知')} · 接收 {time_text(item.get('accepted_at') or item.get('timestamp'))}"
|
||||
+ (f" · 读取 {time_text(item['consumed_at'])}" if item.get("consumed_at") else "")
|
||||
for item in items
|
||||
)
|
||||
or "无指导记录"
|
||||
)
|
||||
|
||||
|
||||
def source_text(value: dict) -> str:
|
||||
labels = {
|
||||
"android": "安卓界面",
|
||||
"computer": "电脑界面",
|
||||
"api": "接口数据",
|
||||
"terminal": "终端",
|
||||
"file": "文件",
|
||||
"other": "其他",
|
||||
}
|
||||
lines = []
|
||||
for item in value.get("sources", []):
|
||||
references = ", ".join(
|
||||
" / ".join(
|
||||
f"{key}={ref[key]}" for key in ("step_id", "call_id", "source_id") if ref.get(key)
|
||||
)
|
||||
or "编号未记录"
|
||||
for ref in item.get("references", [])
|
||||
)
|
||||
lines.append(
|
||||
f"{labels.get(item['kind'], '其他')} · {item['label'] or item['target_id']} · {references}"
|
||||
)
|
||||
if value.get("sources_omitted"):
|
||||
lines.append(f"另 {value['sources_omitted']} 个来源见原始步骤记录。")
|
||||
lines.append(f"来源未完整记录的步骤:{value.get('unattributed_step_count', '未知')}。")
|
||||
lines.append(value.get("note") or "来源清单不代表断言已验证。")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def metadata(report: dict) -> list[tuple]:
|
||||
return [
|
||||
("任务编号", report["id"]),
|
||||
@@ -272,6 +344,9 @@ def metadata(report: dict) -> list[tuple]:
|
||||
("任务目标", report["goal"]),
|
||||
("预期结果", report["expected"] or "未指定"),
|
||||
("执行状态", STATUS.get(report["status"], report["status"])),
|
||||
("耗时分项", lifecycle_text(report.get("lifecycle") or {})),
|
||||
("指导消费", guidance_text(report.get("instructions") or [])),
|
||||
("证据来源与边界", source_text(report.get("evidence_sources") or {})),
|
||||
("验证结论", report["verdict"]),
|
||||
("人工复验时间", time_text((report.get("test_result") or {}).get("reviewed_at"))),
|
||||
(
|
||||
@@ -558,7 +633,19 @@ def word_report(report: dict, path: Path):
|
||||
details = [
|
||||
(label, value)
|
||||
for label, value in metadata(report)
|
||||
if label in {"任务编号", "用例编号", "检测项目", "测试子项", "开始时间", "结束时间", "设备"}
|
||||
if label
|
||||
in {
|
||||
"任务编号",
|
||||
"用例编号",
|
||||
"检测项目",
|
||||
"测试子项",
|
||||
"开始时间",
|
||||
"结束时间",
|
||||
"设备",
|
||||
"耗时分项",
|
||||
"指导消费",
|
||||
"证据来源与边界",
|
||||
}
|
||||
]
|
||||
word_table(doc, details, (3.2, 13.3))
|
||||
doc.add_heading("任务目标与预期" if not report["expected"] else "任务目标", 2)
|
||||
|
||||
Reference in new issue
Block a user