feat: integrate chatbox research with datasets and backtests

This commit is contained in:
yuxuanhui
2026-09-08 12:43:00 +08:00
parent 43336ad960
commit aef8e1d310
37 changed files with 1421 additions and 42 deletions
+26 -6
View File
@@ -161,9 +161,22 @@ class Backtests:
{k: getattr(row, k) for k in ("id", "version", "name", "source", "candidates", "updated_at")}
)
async def preview(self, body):
async def preview(self, body, *, preserve_source=False):
"""Fix inputs; new chatbox candidates inherit trusted generating-run provenance.
Existing draft references and server-side subsets/reruns retain their
producer. ai_context separately identifies whoever starts the execution.
"""
if body.inline:
data = body.inline.model_dump(mode="json")
if self.ai_context and not preserve_source:
data["source"] = {
**data["source"],
"kind": "chatbox",
"reference": self.ai_context["conversation_id"],
"research_id": self.ai_context["ai_run_id"],
"parent_run_id": None,
}
else:
draft = await self.db.scalar(
select(BacktestDraft).where(BacktestDraft.id == body.draft_id).with_for_update()
@@ -316,10 +329,11 @@ class Backtests:
await self.db.flush()
return await self.run(run.id)
async def runs(self, limit=25, offset=0, source=None):
async def runs(self, limit=25, offset=0, source=None, reference=None, research_id=None):
query = select(BacktestRun)
if source:
query = query.where(BacktestRun.source["kind"].as_string() == source)
for key, value in (("kind", source), ("reference", reference), ("research_id", research_id)):
if value:
query = query.where(BacktestRun.source[key].as_string() == value)
total = await self.db.scalar(select(func.count()).select_from(query.subquery()))
rows = (
await self.db.scalars(
@@ -333,6 +347,10 @@ class Backtests:
"offset": offset,
}
async def sources(self):
kinds = await self.db.scalars(select(BacktestRun.source["kind"].as_string()).distinct())
return sorted({kind for kind in kinds if kind} | {"chatbox", "manual"})
async def run(self, run_id):
row = await self.db.get(BacktestRun, run_id)
if not row:
@@ -562,7 +580,8 @@ class Backtests:
for r in selected
],
)
)
),
preserve_source=True,
)
async def attach_reference(self, attempt_id, body):
@@ -603,5 +622,6 @@ class Backtests:
if not candidates:
raise HTTPException(422, "至少保留一条候选")
return await self.preview(
PreviewInput(inline=DraftInput(name=parent.name, source=parent.source, candidates=candidates))
PreviewInput(inline=DraftInput(name=parent.name, source=parent.source, candidates=candidates)),
preserve_source=True,
)