feat: add persisted batch text testing

This commit is contained in:
Xin Wang
2026-08-10 13:49:24 +08:00
parent 5b8b9fd097
commit 19e8c8c108
27 changed files with 3855 additions and 1450 deletions

View File

@@ -422,3 +422,115 @@ class WebhookDelivery(Base):
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
)
class TestSuite(Base):
"""A persisted group of text-based assistant test cases."""
__tablename__ = "test_suites"
id: Mapped[str] = mapped_column(String(40), primary_key=True)
name: Mapped[str] = mapped_column(String(128))
description: Mapped[str] = mapped_column(String(2048), default="")
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now()
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
)
class TestCase(Base):
"""One editable test definition; nested turns remain one JSON document."""
__tablename__ = "test_cases"
__table_args__ = (
UniqueConstraint("suite_id", "sort_order", name="uq_test_case_suite_order"),
)
id: Mapped[str] = mapped_column(String(40), primary_key=True)
suite_id: Mapped[str] = mapped_column(
String(40),
ForeignKey("test_suites.id", ondelete="CASCADE"),
index=True,
)
name: Mapped[str] = mapped_column(String(128))
description: Mapped[str] = mapped_column(String(2048), default="")
input_mode: Mapped[str] = mapped_column(
String(40), default="fixed_script_text", index=True
)
definition: Mapped[dict] = mapped_column(JSONB, default=dict)
sort_order: Mapped[int] = mapped_column(Integer, default=0)
last_result: Mapped[str] = mapped_column(String(16), default="not_run")
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now()
)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
)
class TestRun(Base):
"""One immutable batch-run request plus its aggregate lifecycle state."""
__tablename__ = "test_runs"
id: Mapped[str] = mapped_column(String(40), primary_key=True)
assistant_id: Mapped[str | None] = mapped_column(
String(40),
ForeignKey("assistants.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
assistant_name: Mapped[str] = mapped_column(String(128), default="")
title: Mapped[str] = mapped_column(String(256), default="批量测试")
status: Mapped[str] = mapped_column(String(16), index=True, default="queued")
config: Mapped[dict] = mapped_column(JSONB, default=dict)
stop_reason: Mapped[str | None] = mapped_column(String(32), nullable=True)
cancel_requested: Mapped[bool] = mapped_column(Boolean, default=False)
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now()
)
started_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
finished_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
class TestRunCase(Base):
"""Run-local test case snapshot and detailed execution result."""
__tablename__ = "test_run_cases"
__table_args__ = (
UniqueConstraint("run_id", "test_case_id", name="uq_test_run_case"),
)
id: Mapped[str] = mapped_column(String(40), primary_key=True)
run_id: Mapped[str] = mapped_column(
String(40),
ForeignKey("test_runs.id", ondelete="CASCADE"),
index=True,
)
test_case_id: Mapped[str | None] = mapped_column(
String(40),
ForeignKey("test_cases.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
test_case_name: Mapped[str] = mapped_column(String(128))
suite_id: Mapped[str | None] = mapped_column(String(40), nullable=True)
position: Mapped[int] = mapped_column(Integer, default=0)
case_snapshot: Mapped[dict] = mapped_column(JSONB, default=dict)
status: Mapped[str] = mapped_column(String(16), index=True, default="waiting")
attempt_count: Mapped[int] = mapped_column(Integer, default=0)
max_attempts: Mapped[int] = mapped_column(Integer, default=1)
result: Mapped[dict] = mapped_column(JSONB, default=dict)
execution_error: Mapped[dict | None] = mapped_column(JSONB, nullable=True)
started_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
finished_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)