fix(bioflow): BFF Block union 补 7 种生信块类型,修复骨架消息持久化 422

前端 sendBioflow 的骨架消息(kind=bioflow,blocks 含 bioflow_path 等
生信块)POST 到 BFF 会话持久化时,Block union 无生信块类型 → 422
VALIDATION,会话历史不落库(前端有 catch 不阻断显示)。

- schemas.py 新增 BioflowPathBlock/BioflowProgressBlock/BioflowFormBlock/
  BioflowFileBlock/BioflowArchiveBlock/BioflowQaBlock/BioflowReuseBlock
  (判别字面量+全默认值+extra=allow 宽松接收——字段契约归前端 store
  与 bioflow 服务 SSE,BFF 只做持久化校验)
- 部署:deploy-unified/sdk/app/schemas.py 已同步,8090 重启(0.0.0.0
  绑定保持内网可访问)
- 验证:curl 骨架消息 422→201,7 种块写入/GET 详情/PATCH 检查点/读回
  全通;浏览器端到端(真实生产 BFF)无 4xx、路径卡正常、刷新后会话
  历史恢复保留生信消息与块

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-07 18:43:01 +08:00
co-authored by Claude Fable 5
parent bd011650f6
commit 5457579d02
+101
View File
@@ -101,9 +101,110 @@ class ArtifactBlock(BaseModel):
status: str = "done" # running|done|error(生成中/已就绪/失败)
# ---------------------------------------------------------------------------
# §2b 生信块(BFF 仅做持久化校验,不参与渲染——字段契约归前端 store 与
# bioflow 服务 SSE 事件;union 判别靠 type 字面量,其余字段全默认值 +
# extra="allow" 宽松接收,生信功能只部署 rag 时零影响)。
# ---------------------------------------------------------------------------
class BioflowPathBlock(BaseModel):
"""生信路径选择卡(FR-BIO-002/003/004):候选路径列表 + 选中项。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_path"] = "bioflow_path"
status: str = "running"
candidates: list[dict[str, Any]] = Field(default_factory=list)
selected: Any = None
autoFilled: list[str] = Field(default_factory=list)
reuseArchive: Any = None
reuseName: Any = None
fallback: Any = None
class BioflowProgressBlock(BaseModel):
"""生信阶段进度卡(FR-BIO-013/014):逐阶段状态流转 + 日志尾。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_progress"] = "bioflow_progress"
jobId: Any = None
jobStatus: str = "created"
stages: list[dict[str, Any]] = Field(default_factory=list)
autoContinue: bool = False
class BioflowFormBlock(BaseModel):
"""生信参数确认表单卡(FR-BIO-008/012):阶段参数可编辑表单。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_form"] = "bioflow_form"
stage: str = ""
fields: list[dict[str, Any]] = Field(default_factory=list)
autoContinue: bool = False
rerun: bool = False
submitting: bool = False
class BioflowFileBlock(BaseModel):
"""生信数据文件引导卡(FR-BIO-005/006):缺失文件提示 + 上传进度。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_file"] = "bioflow_file"
stage: str = ""
requiredFiles: list[str] = Field(default_factory=list)
message: str = ""
files: list[dict[str, Any]] = Field(default_factory=list)
class BioflowArchiveBlock(BaseModel):
"""生信存档提示卡(FR-BIO-020):任务完成后提示存档。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_archive"] = "bioflow_archive"
jobId: Any = None
status: str = "pending" # pending | archiving | done | dismissed | error
name: str = ""
description: str = ""
result: Any = None
error: Any = None
class BioflowQaBlock(BaseModel):
"""生信流程知识库咨询引用块(FR-BIO-026):引用携带 cite 供跳转。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_qa"] = "bioflow_qa"
question: str = ""
citations: list[dict[str, Any]] = Field(default_factory=list)
degraded: bool = False
class BioflowReuseBlock(BaseModel):
"""生信存档复用预填表单块(FR-BIO-023):复用存档方法发起新任务。"""
model_config = ConfigDict(extra="allow")
type: Literal["bioflow_reuse"] = "bioflow_reuse"
mode: str = "reuse"
stage: str = "reuse"
archiveId: Any = None
archiveName: str = ""
sessionId: str = ""
target: str = ""
fields: list[dict[str, Any]] = Field(default_factory=list)
prefill: dict[str, Any] = Field(default_factory=dict)
Block = Union[
TextBlock, TableBlock, CodeBlock, StreamBlock,
PipelineBlock, ToolBlock, SourcesBlock, GraphBlock, ArtifactBlock,
BioflowPathBlock, BioflowProgressBlock, BioflowFormBlock, BioflowFileBlock,
BioflowArchiveBlock, BioflowQaBlock, BioflowReuseBlock,
]