feat: release 2.4.0 with original cases and automatic human review

This commit is contained in:
chenmingxuan committed 2026-10-28 17:25:08 +08:00
1 parent baf069854b
commit 4dc2057d43
66 files changed
+1390 -206

No files matched your search

+63 -6
View File
@@ -21,6 +21,7 @@ HEADERS = (
"Artemis提示词",
"任务配置(JSON)",
)
CASE_HEADERS = ("预置条件", "操作步骤", "预期结果")
MAX_ROWS = int(os.getenv("ARTEMIS_IMPORT_MAX_ROWS", "1000"))
MAX_BYTES = int(os.getenv("ARTEMIS_IMPORT_MAX_BYTES", "10485760"))
@@ -61,6 +62,15 @@ class TaskOptions(BaseModel):
return value.model_dump(exclude_unset=True)
class OriginalCase(BaseModel):
"""Imported review material, never appended to the execution prompt."""
model_config = ConfigDict(extra="forbid")
preconditions: str = Field(default="", max_length=10000)
steps: str = Field(default="", max_length=10000)
expected: str = Field(default="", max_length=10000)
class TaskCase(BaseModel):
model_config = ConfigDict(extra="forbid")
case_id: str = Field(default="", max_length=200)
@@ -70,16 +80,29 @@ class TaskCase(BaseModel):
preconditions: str = Field(default="", max_length=10000)
goal: str = Field(min_length=1, max_length=10000)
task_config: TaskOptions = Field(default_factory=TaskOptions)
original_case: OriginalCase | None = None
def original_case_enabled() -> bool:
from apps.admin_console.services.task_extensions import active_manifests
return any(
panel.kind == "original_case"
for manifest in active_manifests()
if manifest.workspace is not None
for panel in manifest.workspace.panels
)
def template() -> bytes:
headers = (*HEADERS, *CASE_HEADERS) if original_case_enabled() else HEADERS
wb = Workbook()
ws = wb.active
assert ws is not None
ws.title = "任务"
ws.append(HEADERS)
ws.append(headers)
ws.freeze_panes = "A2"
ws.auto_filter.ref = "A1:G1"
ws.auto_filter.ref = f"A1:{get_column_letter(len(headers))}1"
for cell in ws[1]:
cell.font = Font(bold=True, color="FFFFFF")
cell.fill = PatternFill("solid", fgColor="245C78")
@@ -93,7 +116,7 @@ def template() -> bytes:
help_sheet.append(["前置约束提取及其他描述列仅作查看、搜索和报告元数据,不追加到提示词。"])
help_sheet.append(["任务配置(JSON)可留空,空字段继承批次或全局配置;禁止密钥与未知字段。"])
help_sheet.append(["示例仅供参考,不会导入执行。请在“任务”页填写自己的用例。"])
help_sheet.append(HEADERS)
help_sheet.append(headers)
help_sheet.append(
[
"示例-001",
@@ -130,7 +153,18 @@ def template() -> bytes:
json.dumps({"profile": "flash", "execution_target": "computer"}, ensure_ascii=False),
]
)
for column in range(1, 8):
if len(headers) > len(HEADERS):
help_sheet.append(
[
"人工评审插件附加列:预置条件、操作步骤、预期结果。仅保存原始用例,均不追加到 AI 提示词。"
]
)
for row_number in (6, 7):
for column, value in enumerate(
("填写原始用例的预置条件", "填写原始用例的操作步骤", "填写原始用例的预期结果"), 8
):
help_sheet.cell(row_number, column, value)
for column in range(1, len(headers) + 1):
help_sheet.column_dimensions[get_column_letter(column)].width = 70 if column > 5 else 26
for row in help_sheet:
for cell in row:
@@ -164,7 +198,10 @@ def parse_workbook(data: bytes) -> dict:
raise ValueError("缺少“任务”工作表,请使用下载的模板")
rows = iter(wb["任务"].iter_rows())
headers = [str(cell.value or "").strip() for cell in next(rows, [])]
if headers != list(HEADERS):
supported_headers = [list(HEADERS)]
if original_case_enabled():
supported_headers.append([*HEADERS, *CASE_HEADERS])
if headers not in supported_headers:
raise ValueError("列名或顺序与新版模板不一致,请重新下载模板")
tasks, errors = [], []
for number, row in enumerate(rows, 2):
@@ -190,9 +227,29 @@ def parse_workbook(data: bytes) -> dict:
"preconditions": values[4],
"goal": values[5],
"task_config": config,
"original_case": (
dict(
zip(
("preconditions", "steps", "expected"),
(
str(cell.value if cell.value is not None else "").strip()
for cell in row[7:10]
),
)
)
if len(headers) == 10
else None
),
}
)
tasks.append(
{
"row": number,
**case.model_dump(
exclude={"original_case"} if case.original_case is None else None
),
}
)
tasks.append({"row": number, **case.model_dump()})
except (ValueError, TypeError) as exc:
errors.append({"row": number, "message": str(exc)[:500]})
if not tasks and not errors: