feat: support image inputs in assistant tests

This commit is contained in:
Xin Wang
2026-08-23 23:46:18 +08:00
parent 0966f382b6
commit 9e4dfbe596
26 changed files with 1010 additions and 146 deletions
+17 -2
View File
@@ -18,6 +18,8 @@ from fastapi import APIRouter, Depends, HTTPException
from services.auth import require_admin
from services.config_resolver import resolve_runtime_config
from services.runtime_variables import DynamicVariableError, prepare_dynamic_config
from services.realtime.launcher import validate_visual_runtime
from services.test_case_assets import canonicalize_test_assets, image_asset_ids
from services.test_runs.orchestrator import test_run_orchestrator
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
@@ -140,13 +142,18 @@ async def create_test_run(
raise HTTPException(422, "测试用例不存在: " + "、".join(missing))
ordered_cases = [by_id[case_id] for case_id in body.case_ids]
tools_by_id = {tool.id: tool for tool in runtime_config.tools}
definitions_by_id: dict[str, TestCaseDefinition] = {}
has_image_input = False
for row in ordered_cases:
if row.input_mode != "fixed_script_text":
raise HTTPException(422, f"用例“{row.name}”不是可运行的固定文字模式")
raise HTTPException(422, f"用例“{row.name}”不是可运行的固定多模态模式")
try:
definition = TestCaseDefinition.model_validate(row.definition or {})
await canonicalize_test_assets(session, definition)
except ValueError as exc:
raise HTTPException(422, f"用例“{row.name}”校验失败: {exc}") from exc
definitions_by_id[row.id] = definition
has_image_input = has_image_input or bool(image_asset_ids(definition))
for turn in definition.turns:
for behavior in turn.behaviors:
if behavior.type != "tool_call":
@@ -159,6 +166,14 @@ async def create_test_run(
"不属于当前被测助手",
)
if has_image_input:
try:
vision_enabled = validate_visual_runtime(runtime_config)
except ValueError as exc:
raise HTTPException(422, str(exc)) from exc
if not vision_enabled:
raise HTTPException(422, "测试用例包含图片,但当前助手未开启视觉能力")
suite_ids = list(dict.fromkeys(row.suite_id for row in ordered_cases))
suites = (
await session.execute(select(TestSuite).where(TestSuite.id.in_(suite_ids)))
@@ -192,7 +207,7 @@ async def create_test_run(
)
session.add(run)
for position, row in enumerate(ordered_cases):
definition = TestCaseDefinition.model_validate(row.definition or {})
definition = definitions_by_id[row.id]
snapshot = {
"id": row.id,
"suiteId": row.suite_id,