chore(prep): shared groundwork for batch-4 (report pipeline)
第四批(T15 编排/T16 视觉诊断/T17 文案校验)协调提交: - 迁移 0006:rp_report(result JSONB 按阶段键承载中间态)/rp_input (derived_features 视觉中间态)/rp_share(V1 只建结构) - ORM 三模型;错误码 40420/40920(文案无价格字样) - 配置:report_pipeline_stages(dotted path 动态装配)+ vision/tier - packages/report/pipeline.py:Stage Protocol + ReportContext(三任务共同契约, 动态 import 的动机与代价写在 docstring) - 路由桩 reports.py 已注册
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
"""报告流水线的阶段契约(第四批 T15/T16/T17 的共同接口)。
|
||||
|
||||
本文件由协调提交只定 **接口**;编排实现(assemble_stages / run_pipeline)
|
||||
归 T15。T16 提供 vision_stage / diagnosis_stage,T17 提供 copy_stage /
|
||||
validation_stage——三个任务互不改对方文件,靠 Settings.report_pipeline_stages
|
||||
里的 dotted path 动态装配。
|
||||
|
||||
设计动机(为什么动态 import):三个阶段模块由三个并行分支各自创建,
|
||||
静态 import 会在任一分支缺文件时炸掉编排;按配置动态装配让每个分支
|
||||
独立可测,合并后自动咬合。代价是 import-linter 看不到这条边——阶段模块
|
||||
自身的依赖仍受契约约束,编排层注入的 session/gateway 都是既有合法依赖。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Protocol, runtime_checkable
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from packages.llm.gateway import LLMGateway
|
||||
from packages.shared.config import Settings
|
||||
from packages.shared.models import RpInput, RpReport
|
||||
|
||||
|
||||
class ReportContext:
|
||||
"""一个阶段的执行上下文。
|
||||
|
||||
不是 frozen:阶段要写 ``ctx.report.result[stage.name]`` 与
|
||||
``ctx.rp_input.derived_features``(中间态落库由编排层 flush)。
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
report: RpReport,
|
||||
report_input: RpInput,
|
||||
session: AsyncSession,
|
||||
settings: Settings,
|
||||
gateway: LLMGateway | None = None,
|
||||
) -> None:
|
||||
self.report = report
|
||||
self.report_input = report_input
|
||||
self.session = session
|
||||
self.settings = settings
|
||||
self.gateway = gateway
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class Stage(Protocol):
|
||||
"""流水线阶段。name 同时是 result JSONB 里的产物键。
|
||||
|
||||
约定:阶段把自己的全部产物写进 ``ctx.report.result[self.name]``;
|
||||
抛异常即整条流水线失败(编排层负责 tk_task→failed + refund)。
|
||||
"""
|
||||
|
||||
name: str
|
||||
|
||||
async def run(self, ctx: ReportContext) -> None: ...
|
||||
|
||||
|
||||
#: T15 的 assemble_stages 按此清单 importlib 动态导入;缺失即 CONFIG_ERROR。
|
||||
DEFAULT_STAGE_PATHS: tuple[str, ...] = (
|
||||
"packages.report.vision_stage:VisionStage",
|
||||
"packages.report.diagnosis_stage:DiagnosisStage",
|
||||
"packages.report.copy_stage:CopyStage",
|
||||
"packages.report.validation_stage:ValidationStage",
|
||||
)
|
||||
|
||||
|
||||
def stage_names(result: dict[str, Any]) -> list[str]:
|
||||
"""result JSONB 里已出现的阶段键(诊断/调试用的小工具)。"""
|
||||
return [k for k in result if isinstance(result[k], dict)]
|
||||
Reference in New Issue
Block a user