152 lines
10 KiB
Python
152 lines
10 KiB
Python
# ============================================================
|
||
# 跨层契约的 pydantic 运行时形态(moduleId: server-contracts, 可重生 ✅)
|
||
# 与 shared/schemas/*.json 保持一一对应(JSON Schema 为源,py/ts 为镜像)
|
||
# 任何跨层数据必须经过这里的模型校验后才能流转(plan.md §12 规范 6)
|
||
# ============================================================
|
||
from __future__ import annotations # 允许前向类型引用
|
||
|
||
from typing import Any, Literal, Optional # 类型标注工具
|
||
from pydantic import BaseModel, Field # 契约校验基座
|
||
|
||
INTERFACE_VERSION = "1.0"
|
||
|
||
|
||
# ---------------- 视口命令(shared/viewport_command.schema.json) ----------------
|
||
class ViewportCommand(BaseModel):
|
||
"""视口命令:驱动右侧可视化的结构化指令(§6.3)。权力等级:P0(纯视图状态)。"""
|
||
# 命令名:viewport.* 改视口状态;world.refresh 通知前端重拉世界数据
|
||
cmd: Literal[
|
||
"viewport.mode", "viewport.filter", "viewport.focus",
|
||
"viewport.highlight", "viewport.timescale", "viewport.reset",
|
||
"world.refresh",
|
||
]
|
||
# 目标对象 ID(如聚焦的产线 ID),无目标时为 None
|
||
target: Optional[str] = None
|
||
# 命令参数(按 cmd 而异,前端按约定读取)
|
||
params: dict[str, Any] = Field(default_factory=dict)
|
||
# 发起方:LLM 解析产出 / 用户手点 / 系统自动
|
||
issuedBy: Literal["LLM", "USER", "SYSTEM"] = "SYSTEM"
|
||
interfaceVersion: Literal["1.0"] = INTERFACE_VERSION
|
||
|
||
|
||
# ---------------- UI 块(shared/ui_block.schema.json) ----------------
|
||
class UIAction(BaseModel):
|
||
"""UI 块内的可触发动作:用户点击后回传后端(§6.2)。"""
|
||
actionId: str # 动作 ID(后端据此路由)
|
||
label: str # 按钮文案
|
||
power: Literal["P0", "P1", "P2", "P3"] # 权力等级(P2/P3 必须过门禁)
|
||
payload: dict[str, Any] = Field(default_factory=dict) # 携带参数
|
||
|
||
|
||
class UIBlock(BaseModel):
|
||
"""UI 块:后端与前端之间的渲染契约(§6.2)。M3 新增 report(报告预览 §9.10)。"""
|
||
blockId: str # 块唯一 ID
|
||
type: Literal["text", "confirm-card", "evidence", "scenario-cards", "report",
|
||
"flex-schedule", "flex-capacity", "flex-due", "flex-compare",
|
||
"plan-trace", "conflict-center",
|
||
"kpi-dashboard", "compare-table", "guidance",
|
||
"readiness", "clarify", "wizard", "folder-pack", "project-analyze", "drawing-analysis"]
|
||
props: dict[str, Any] = Field(default_factory=dict) # 数据载荷
|
||
actions: list[UIAction] = Field(default_factory=list) # 块内动作
|
||
evidenceRefs: list[str] = Field(default_factory=list) # 关联证据 ID
|
||
interfaceVersion: Literal["1.0"] = INTERFACE_VERSION
|
||
|
||
|
||
# ---------------- 结构化工具请求(shared/intent.schema.json) ----------------
|
||
# 工具名的封闭枚举:Pi Agent 只能调用此集合内的已登记工具,超出即拒绝。
|
||
IntentName = Literal[
|
||
"schedule.run", "schedule.publish",
|
||
"order.upsert", "order.cancel", "order.complete", "order.delete", "order.clear", # M4:订单管理(P2)
|
||
"order.submit", "order.approve", "order.reject", # OR-03:订单池审核
|
||
"order.pool", # OR-03:订单池摘要(P0)
|
||
"rush.evaluate", "rush.apply", # OR-04:紧急插单快评 / 采用
|
||
"forecast.query", "forecast.upsert", "forecast.delete", "forecast.convert", # OR-05
|
||
"plan.buckets", # PL-01:时间分桶计划
|
||
"plan.rccp", # PL-02:有限/无限粗能力对照
|
||
"plan.feasibility", # PL-03:交期可行性
|
||
"plan.inventory", # PL-04:库存投影
|
||
"plan.leveling", # PL-05:产能平衡/削峰
|
||
"plan.supply", # PL-06:产供方向决策
|
||
"order.decompose", "mrp.release", # M4:订单分解 MRP(P1)/ 建议单下达(P2)
|
||
"plan.trace", # M4:计划追溯 SO→主数据→分解→PO/WO→负荷/库存
|
||
"master.material.upsert", # 对话新建/编辑物料(P2)
|
||
"master.changeover.upsert", # MD-06:换型矩阵写入(P2)
|
||
"master.clear", # 一键清理主数据板块(P2)
|
||
"master.query", # 自然语言检索订单/物料/BOM/工艺(P0)
|
||
"changeover.query", # MD-06:换型矩阵只读
|
||
"campaign.preview", # SC-08:战役合并预览
|
||
"params.update", # OR-02:排产参数更新(P2)
|
||
"params.query", # OR-02:排产参数查询(P0)
|
||
"constraint.profile.query", # SC-04:约束剖面查询(P0)
|
||
"constraint.profile.save", # SC-04:约束剖面保存(P2)
|
||
"data.import", # 自然语言批量导入订单/物料(P2)
|
||
"import.commit", # Excel/CSV 导入入库(P2)
|
||
"folder.analyze", # 工程目录深度解析(P0)
|
||
"folder.schedule", # 导入工程目录并试排(P2)
|
||
"flex.site.load", # 现场完整生产路线 → 替换 flex*(P2)
|
||
"flex.schedule", "flex.reschedule", "flex.swap", "flex.capacity", "flex.simulate_due",
|
||
"flex.compare", "flex.rush", "flex.fault", "flex.resource.patch", "flex.conflict.resolve",
|
||
"conflict.list", "flex.adjust.preview", "flex.adjust.commit",
|
||
"schedule.adjust.preview", "schedule.adjust.commit",
|
||
"sap.status", "sap.sync.inbound", "sap.sync.outbound",
|
||
"mes.status", "mes.dispatch", "mes.report",
|
||
"scenario.compare", # M2:多策略沙盒对比(Explore 通道 §5.1)
|
||
"scenario.sensitivity", # SC-06:敏感性分析 Tornado
|
||
"sop.compile", "sop.apply", # IND-02:SOP→约束编译 / 应用
|
||
"checkpoint.create", "checkpoint.rollback", # M2:成对快照与回滚(§4.3)
|
||
"knowledge.query", # M3:知识库检索(带出处 §8.2)
|
||
"knowledge.import", # RAG:导入知识文档(P2)
|
||
"skill.list", "skill.health", # 外部算法 skill 清单/健康检查(P0)
|
||
"skill.register", "skill.enable", # 登记/启停 skill(P2)
|
||
"readiness.query", # M-B:数据齐备度检查(P0)
|
||
"data.analyze", # 分析项目/文件数据与排产缺口(P0)
|
||
"assistant.reply", # 通用排产助理作答(P0,带项目上下文)
|
||
"flex.time.update", # M-B:工时维护(P2)
|
||
"schedule.wizard", # M-F:引导式排产向导
|
||
"guidance.next", # AG-07:主动引导下一步建议
|
||
"report.generate", # M3:报告生成(日报/版本对比 §9.10)
|
||
"viewport.mode", "viewport.filter", "viewport.focus",
|
||
"viewport.highlight", "viewport.timescale", "viewport.reset",
|
||
"query.kpi", "data.reset", "help", "unknown",
|
||
]
|
||
|
||
|
||
class IntentResult(BaseModel):
|
||
"""Pi Agent 的结构化工具请求(不是自然语言意图识别结果)。"""
|
||
intent: IntentName # 工具名(封闭枚举)
|
||
params: dict[str, Any] = Field(default_factory=dict) # 槽位参数(策略/模式/客户名…)
|
||
confidence: float = Field(ge=0, le=1) # 请求置信度(保留字段,工具执行以登记与门禁为准)
|
||
source: Literal["RULE_FAST", "LLM"] = "LLM" # 产生来源;RULE_FAST 仅为历史审计兼容
|
||
interfaceVersion: Literal["1.0"] = INTERFACE_VERSION
|
||
|
||
|
||
# ---------------- 排产结果摘要(shared/schedule_result.schema.json) ----------------
|
||
class ScheduleResult(BaseModel):
|
||
"""排产结果摘要:引擎 solve() 的标准输出(§9.1),回复/审计/KPI 共用。"""
|
||
versionId: int # 版本 ID
|
||
versionNo: str # 版本号(V+日期+序号)
|
||
engineType: Literal["RULE", "CP", "GA", "HYBRID", "EXTERNAL", "OPTIMIZE"] # 引擎类型
|
||
strategy: str # 策略模板
|
||
status: Literal["DRAFT", "PUBLISHED", "ARCHIVED"] = "DRAFT" # 版本状态
|
||
orderCount: int # 参与排产的订单项数
|
||
poCount: int # 生成生产订单数
|
||
woCount: int # 生成工单数
|
||
conflictCount: int # 冲突数
|
||
totalTardiness: float # 总延迟(小时)
|
||
avgUtilization: float # 平均利用率 0-1
|
||
totalCost: float = 0 # 预估成本
|
||
evidenceRefs: list[str] = Field(default_factory=list) # 证据引用(run-id)
|
||
# SC-03:求解器元信息(RULE 可空;CP 填 status/gap/耗时)
|
||
solveStatus: str | None = None # OPTIMAL / FEASIBLE / INFEASIBLE / MODEL_INVALID / …
|
||
solveTimeSec: float | None = None # 墙钟秒
|
||
optimalityGap: float | None = None # |(obj-bound)/obj|;最优时约 0
|
||
|
||
|
||
# ---------------- 智能体回复(SSE 载荷的聚合形态,仅后端内部使用) ----------------
|
||
class AgentReply(BaseModel):
|
||
"""一轮对话的完整产出:文本 + 视口命令 + UI 块(gateway 将其拆成 SSE 事件流)。"""
|
||
text: str # 回复正文(前端流式渲染)
|
||
commands: list[ViewportCommand] = Field(default_factory=list) # 要执行的视口命令
|
||
blocks: list[UIBlock] = Field(default_factory=list) # 附加 UI 块(如确认卡)
|
||
intent: Optional[IntentResult] = None # 本轮结构化工具请求(协议证据)
|