Files
SystemSimulationApp/docs/standard/component-library-spec-v1.md
T

33 KiB
Raw Blame History

组件库分类、发现与读取规范 v1

文档版本:1.2.0 修订日期:2026-09-12 核对代码基线:22579e5 加本次输入合同实现;配套工程 JSON v2,XML v3 和模型版本不变。

状态:已在 experimental 与 amesim 组件库实施;本版按注册演练校正 适用范围:app/simulation/components、组件注册中心、System XML 和 React Flow 组件库 当前启用库:experimental(前端按库 ID 隐藏)、amesim(前端可见)。完整接入顺序见新组件注册流程,实际演练见注册示例与验证。

0. 文档定位

本文档只负责“模型如何被系统发现和读取”。模型方程、状态、参数和结果应如何编写, 统一参见组件模型建模规范 v1。

人工或 AI 排查组件读取问题时,按以下顺序读取:

  1. app/simulation/registry.py 中的 ENABLED_COMPONENT_LIBRARIES。
  2. 被启用组件库的 library.py。
  3. library.py/models 明确列出的模型类。
  4. 模型类的 DISPLAY / PORTS / PARAMETERS。
  5. build_component_catalog() 的输出。
  6. 前端 normalizeComponentCatalog()。

当前事实来源优先级:

信息 唯一事实来源 不能作为事实来源
启用哪些库 ENABLED_COMPONENT_LIBRARIES 目录中碰巧存在的文件夹
库分类和模型清单 各库 library.py 前端组件列表
模型类型和版本 模型类 文件名或中文名称
物理端口 模型类 PORTS DISPLAY.ports 或画布方向
参数默认值和边界 模型类 PARAMETERS 前端兜底定义
图标和端口位置 模型类 DISPLAY 物理方程
前端运行目录 /api/components/catalog 手工扫描 Python 包

如果文档、代码和目录响应不一致,应在同一次修改中修复并增加测试,不能通过复制 另一份映射临时绕过。

1. 目标

本规范用于统一以下内容:

  1. 后端组件库如何声明自身信息和分类。
  2. 单个模型如何声明端口、参数、结果变量和界面显示信息。
  3. 后端如何发现、校验、注册并实例化模型。
  4. 前端如何通过统一目录接口自动生成左侧组件库和参数面板。
  5. System XML 中的模型类型如何稳定映射到 Python 实现。

目标工作流如下:

flowchart LR
    A["ENABLED_COMPONENT_LIBRARIES"] --> B["library.py"]
    B --> C["受控导入模型类"]
    C --> D["启动契约校验"]
    D --> E["组件注册表"]
    E --> F["GET /api/components/catalog"]
    F --> G["React Flow 组件库和参数面板"]
    E --> H["System XML 模型实例化"]

普通固定端口、已有参数编辑器和单位的模型由目录生成组件列表及参数面板,无需再复制型号定义。新图形、动态端口、新编辑器、新单位或物理域仍须补齐对应前端支持,见注册流程的条件修改表。上图只表示元数据发现;模型参与仿真还需原生发现、支持版本、方程生成及 C 模块链接。

2. 术语和层级

组件目录采用四个相互独立的概念:

层级 示例 含义
组件库 Library experimental 一组具有共同发布、维护和版本边界的模型
界面分类 Category storage 只用于组件面板分组和排序
物理域 Domain pneumatic 决定端口能否连接以及采用哪组连接方程
模型 Model cylinder 可实例化并写入 System XML 的稳定模型类型

分类和物理域禁止混用。例如,storage 是界面分类,pneumatic 是物理域; 一个“储能元件”也可以属于液压域,不能根据分类推断端口连接规则。

标准层级为:

Library
  Category
    Model
      Port
        Port variable
      Parameter
      Result variable

3. 推荐目录结构

每个组件库使用独立 Python 包:

app/simulation/components/
  experimental/
    __init__.py
    library.py
    storage/
      __init__.py
      cylinder.py
      tank.py
    flow/
      __init__.py
      orifice.py
      resistive_pipe.py
    junctions/
      __init__.py
      tee.py

规则如下:

  • library.py 是组件库唯一清单入口。
  • 分类目录名必须与分类 ID 一致。
  • 一个公开模型原则上放在一个独立 .py 文件中。
  • 求解器、介质、通用方程和状态对象不得放入组件库目录。
  • 未准备对外注册的实验类可以保留在库内,但不得加入库清单。
  • 禁止通过扫描任意 .py 文件并执行其中代码来发现模型;必须使用库清单进行受控导入。

4. 标识符和版本

4.1 标识符

以下字段使用稳定的英文机器标识:

  • library.id
  • category.id
  • MODEL_TYPE
  • 端口名
  • 参数名
  • 结果变量名

库 ID、分类 ID、模型类型及端口名使用小写字母开头的小写字母、数字和下划线。参数和结果变量按成员标识符规则允许大小写字母,以字母开头,例如 T0、T、U;具体校验以注册器的标识符规则为准。

界面中文名称单独保存在 label 中。修改 label 不影响工程兼容性;修改机器标识 会影响工程文件、System XML、结果文件和后端注册,因此发布后不得直接改名。

4.2 版本

每个组件库和模型都应具有版本:

LIBRARY_VERSION = "0.1.0"
MODEL_VERSION = "1.0.0"

版本遵循 主版本.次版本.修订版本(当前校验接受三段数字,不接受预发布或构建后缀):

  • 修订版本:只修复实现,不改变输入输出契约。
  • 次版本:向后兼容地新增参数、结果或能力。
  • 主版本:端口、参数语义或方程发生不兼容变化。

当前 System XML v3 要求每个 Component 显式保存 modelVersion,并与注册模型 版本完全一致;不一致时拒绝加载,不做静默升级。v3 不另存 library,而由全局唯一的 Component/@type 定位注册模型。当前没有通用迁移框架;前端有部分型号专用迁移逻辑,不能推断新型号会自动迁移。 因此当前“修订/次版本向后兼容”只表示合同设计意图,不表示旧 XML 会被解析器自动 接受;任意模型版本变化都会使旧 XML 的精确版本检查失败。

5. 组件库清单

每个库必须提供 library.py,并使用有类型的不可变声明:

from app.simulation.core.catalog import (
    ComponentCategorySpec,
    ComponentLibrarySpec,
)

LIBRARY = ComponentLibrarySpec(
    id="experimental",
    label="临时测试组件库",
    version="0.1.0",
    source_package="app.simulation.components.experimental",
    temporary=True,
    order=100,
    categories=(
        ComponentCategorySpec(
            id="storage",
            label="储能元件",
            order=10,
        ),
        ComponentCategorySpec(
            id="flow",
            label="流动元件",
            order=20,
        ),
        ComponentCategorySpec(
            id="junctions",
            label="连接元件",
            order=30,
        ),
    ),
    models=(
        "app.simulation.components.experimental.storage.cylinder:Cylinder",
        "app.simulation.components.experimental.storage.tank:Tank",
        "app.simulation.components.experimental.flow.resistive_pipe:ResistivePipe",
        "app.simulation.components.experimental.flow.orifice:Orifice",
        "app.simulation.components.experimental.junctions.tee:Tee",
    ),
)

models 是唯一允许注册到系统的模型清单。它同时解决以下问题:

  • 避免导入测试脚本或内部辅助类。
  • 控制模型加载顺序。
  • 避免同一个 MODEL_TYPE 被多个实现重复注册。
  • 可以只加载部署环境允许使用的组件库。
  • 启动错误能明确定位到具体库和模型。

当前 experimental/library.py 已按此格式声明库、分类和五个公开模型; experimental/__init__.py 只公开规范化的 LIBRARY 清单。

6. 模型类契约

一个可注册模型必须显式声明:

class ExampleComponent(Component):
    MODEL_TYPE = "example_component"
    MODEL_VERSION = "1.0.0"
    PORTS = (...)
    PARAMETERS = (...)
    RESULT_VARIABLES = (...)
    DISPLAY = ...

字段含义:

字段 是否必须 用途
MODEL_TYPE 必须 System XML、注册表和结果元数据中的稳定类型
MODEL_VERSION 必须 模型契约和迁移版本
PORTS 必须 物理或信号连接契约
PARAMETERS 必须,可为空 用户输入参数及校验边界
RESULT_VARIABLES 必须,可为空 组件级可展示结果
DISPLAY 必须 前端名称、分类、图标、排序和端口布局

模型实现还必须满足:

  1. 构造函数调用 super().__init__(name)。
  2. 使用 set_parameter_values() 保存所有规范化后的参数。
  3. 使用 register_declared_port() 创建 PORTS 中声明的端口。
  4. 可见组件结果对应 RESULT_VARIABLES 中 visible=True 的项;端口结果对应活动端口的可见变量。
  5. 所有内部计算均使用 SI 基准值。
  6. 模型不能直接依赖 FastAPI、React Flow 或 XML DOM。
  7. 模型的方程不能依赖图标方向、界面分类或画布位置。

完整方程示例参见 注册示例与验证。

7. 界面显示声明

DISPLAY 的图形、布局和分组描述前端呈现,不定义物理公式。例外是已实现的介质 role:前端及 XML 使用它做引用识别;后端网络另按介质定义基类判断,新增介质必须同步二者。普通显示声明示例:

from app.simulation.core.catalog import (
    ComponentDisplaySpec,
    PortDisplaySpec,
)

DISPLAY = ComponentDisplaySpec(
    label="示例容腔",
    library_id="experimental",
    category_id="storage",
    symbol="cylinder",
    order=90,
    ports=(
        PortDisplaySpec(
            name="port_a",
            side="left",
            order=10,
        ),
    ),
)

字段规则:

  • label:组件库中的显示名称。
  • library_id:必须引用已加载的库。
  • category_id:必须引用该库已声明的分类。
  • symbol:前端图形渲染器的稳定标识。
  • order:同一分类中的排序值。
  • ports:只声明端口在图形中的位置和顺序。

DISPLAY.ports 中的端口名必须与模型的 PORTS 完全一致,不能缺少、增加或改名。 旋转和镜像只改变前端计算后的视觉方位,不改变端口机器名和物理语义。

前端遇到未知 symbol 时必须显示通用占位图标,同时保留模型拖拽、参数编辑、 连线和 XML 生成功能,不能因为缺少专用图形而丢弃整个模型。

8. 端口规范

端口由 PortDefinition 声明:

PORTS = (
    PortDefinition.pneumatic(
        "port_a",
        nominal_role="bidirectional",
    ),
)

每个端口必须包含:

  • 稳定端口名。
  • kind:physical 或 signal。
  • domain:例如 pneumatic。
  • nominal_role:用于界面提示,不决定实际流向。
  • positive_flow_direction:物理流量变量的符号约定。
  • 端口变量及各自连接规则。

当前气动功率端口包含:

变量 角色 连接规则 单位
p effort equal Pa
m_flow flow sumToZero kg/s
h_outflow stream streamMix J/kg
volume signal directed m3
volume_flow signal directed m3/s

气动端口统一约定 m_flow > 0 表示质量流入当前组件。inlet、outlet 是标称角色, 不应阻止反向流动;实际方向由求解结果中的流量符号决定。

连接校验至少包括:

  1. 两个端口均存在。
  2. 端口不能连接自身。
  3. kind 相同。
  4. domain 相同。
  5. 端口变量集合及连接规则兼容。
  6. 同一物理端口的连接数量符合当前网络编译器能力。

9. 参数规范

参数使用 ParameterDefinition 声明:

PARAMETERS = (
    ParameterDefinition(
        name="volume",
        label="容积",
        quantity="volume",
        unit="m3",
        default=0.1,
        minimum=0.0,
        minimum_exclusive=True,
    ),
)

规则如下:

  • name 是模型构造、XML 和工程文件共同使用的稳定名称。
  • label 是界面文案。
  • quantity 是受控物理量标识,用于前端匹配可换算单位。
  • unit 是后端 SI 单位。
  • default 必须能够直接创建合法模型。
  • 边界必须与方程有效范围一致。
  • 无量纲量使用 quantity="dimensionless" 和 unit=""。
  • 用户输入可以使用其他公制单位,但提交后端前必须换算为 SI。
  • 文本框编辑中的临时字符串不立即判错,失焦、回车或运行仿真时再执行数值校验。

后端不得静默忽略未知参数。Python 工厂可补齐声明默认值,XML 本身必须写全参数;出现未知参数时必须 返回包含组件 ID 和参数名的明确错误。

10. 结果变量规范

组件结果和端口结果分开管理:

  • 组件结果来自 RESULT_VARIABLES 中 visible=True 的项。
  • 端口结果根据活动端口中 result_visible=True 的变量自动生成。
  • 求解器缓存、残差和调试量默认不进入用户结果。

每个结果变量必须提供:

  • name
  • label
  • quantity
  • unit
  • category
  • order

仿真结果必须输出结构化元数据,前端禁止拆解结果键或按字符串关键词猜测:

{
  "key": "cylinder_1.port_b.p",
  "componentId": "cylinder_1",
  "componentType": "cylinder",
  "scope": "port",
  "portName": "port_b",
  "name": "p",
  "label": "压力",
  "quantity": "pressure",
  "unit": "Pa",
  "category": "effort",
  "order": 10
}

结果页应按 componentId、scope、portName、quantity 等结构化字段筛选, 而不是从 key 中推断组件、端口和变量。

11. 标准模型创建入口

注册中心通过统一入口创建模型,避免长期维护集中式 _cylinder_factory、 _tank_factory 等适配函数。当前接口为:

@classmethod
def create(
    cls,
    *,
    name: str,
    medium: IdealGasMedium,
    parameters: Mapping[str, float],
) -> Component:
    ...

创建流程:

  1. 注册中心按 PARAMETERS 填充默认值。
  2. 校验数值有限性和上下限。
  3. 拒绝未知参数。
  4. 调用模型类的 create()。
  5. 验证实例的模型类型、端口和参数快照。
  6. 将实例交给网络编译器。

这种方式允许 Python 构造参数保留内部命名,同时对外始终使用规范中的参数名。

12. 自动发现与注册

后端启动时按以下顺序建立注册表:

读取启用的 library.py
    -> 校验库 ID、版本和分类
    -> 按 models 清单导入模型类
    -> 读取模型静态契约
    -> 执行跨字段校验
    -> 建立 library registry
    -> 建立 model registry
    -> 构建前端 catalog

当前使用显式启用列表:

ENABLED_COMPONENT_LIBRARIES = (
    "app.simulation.components.experimental.library:LIBRARY",
    "app.simulation.components.amesim.library:LIBRARY",
)

禁止以下发现方式:

  • 在整个仓库递归导入所有 Python 文件。
  • 依赖文件名自动推断 MODEL_TYPE。
  • 由前端硬编码后端类路径。
  • 导入失败后悄悄跳过模型。
  • 多个实现重复注册同一个模型类型并由加载顺序决定最终结果。

发现或校验失败时,FastAPI 应拒绝启动并给出库 ID、模型类型、字段和原因。

此启用列表仅控制注册中心。当前 native_codegen/extended.py::catalog_contracts() 另外显式读取两个内置库;新增第三个库必须同步该入口。contracts.py::SUPPORTED_VERSIONS 是独立的原生支持承诺,加入清单和支持版本后仍需实现状态、方程及输出映射。缓存不会替代这些接入步骤。

13. 启动校验规则

注册表完成前必须执行以下校验:

13.1 库与分类

  • 库 ID 全局唯一。
  • 库版本格式有效。
  • 分类 ID 在库内唯一。
  • 所有排序值为整数。
  • 所有模型引用已存在的库和分类。

13.2 模型

  • MODEL_TYPE 全局唯一,且与注册键一致。
  • 模型版本格式有效。
  • 模型继承框架要求的基类。
  • 模型提供统一创建入口。
  • 默认参数能够成功创建实例。

13.3 端口

  • 端口名在模型内唯一。
  • 显示端口集合与 PORTS 声明集合完全一致,包含物理端口与信号端口。
  • 端口物理域、变量角色和连接规则有效。
  • 实例实际注册的端口与静态声明一致。

13.4 参数

  • 参数名在模型内唯一。
  • 默认值有限且满足边界。
  • minimum <= maximum。
  • quantity 和 unit 的组合已登记。
  • 实例保留所有规范化参数,不得静默修改或丢失。

13.5 结果

  • 结果变量名在对应作用域内唯一。
  • quantity 和单位有效。
  • 检查组件结果声明的名称、物理量、单位和分类;启动时不执行数值求解。
  • 端口结果只来自活动端口中声明为可见的变量。

Python component_result_values() 已移除。生成器须为 result_variable_metadata() 中全部可见键提供 C 输出映射;映射完整性和实际数值分别在原生生成、EXE 运行测试中验证,不应写成启动校验已覆盖。

14. 前端组件目录协议

前端只通过以下接口读取组件库:

GET /api/components/catalog

目录顶层必须具有版本:

{
  "schemaVersion": 1,
  "libraries": []
}

单个模型至少包含:

{
  "type": "cylinder",
  "modelType": "cylinder",
  "modelVersion": "1.0.0",
  "label": "气瓶",
  "symbol": "cylinder",
  "order": 10,
  "category": {
    "id": "storage",
    "label": "储能元件",
    "order": 10
  },
  "ports": [],
  "parameters": []
}

前端读取规则:

  1. 按库 order、分类 order、模型 order 排序。
  2. 使用 type 作为拖拽数据和工程文件中的稳定类型。
  3. 使用 label 显示中文名称。
  4. 使用 ports 生成 React Flow Handle。
  5. 使用 parameters 生成参数输入和单位选择控件。
  6. 使用 symbol 选择图标渲染器。
  7. 不在前端重新定义参数默认值、边界或端口语义。

目录协议提供以下可选的参数编辑器与 AMESim 介质扩展字段:

  • 参数的 editor: "choice" 表示数值是稳定的离散编码,必须同时提供非空 options: [{"value": 1, "label": "..."}]。前端显示标签,但工程、XML 与 求解器仍保存和接收 value 数值,不得把标签写入模型数据。
  • 参数可通过 visibleWhen: [{"parameter": "mode", "values": [1, 2]}] 声明显示条件。多个条件之间按 AND 处理,同一条件的多个 values 按 OR 处理;控制参数必须拥有固定 options。隐藏参数的既有值必须保留,不能因 界面联动而重置或从工程、XML 中删除。
  • 模型可通过可选的 parameterGroups 声明纯展示用参数分组。每组包含稳定的 id、显示 label、组间 order、有序参数名数组 parameters 和布尔值 defaultExpanded;默认应为 false。同一参数最多属于一个组,组内参数名 必须引用该模型已注册的参数。分组不改变参数默认值、条件显示、工程保存或 System XML 语义;无分组的模型不输出该字段。
  • 参数的 editor: "amesimGasReference" 表示该数值不是普通连续量,而是 项目介质定义的 gi 引用。前端应保留索引 0,并从当前画布的介质定义 组件生成其余下拉项;索引下拉项只显示数值,不拼接介质名称或中文说明。
  • 参数的 editor: "amesimGasPropertyModel" 表示该参数选择介质定义内部的 物性计算模型。参数同时提供 options: [{"value": 0, "label": "理想气体"}] 一类目录数据,前端据此生成下拉栏;后续增加算法时由介质模型注册新的选项, 前端不硬编码算法名称。
  • 模型的 role: "amesimGasMediumDefinition" 表示该模型是项目级介质定义。 此类模型允许 ports: [],在 System XML v3 中仍按普通零端口 Component 保存;XML 不写任何 Port 快照,只保存模型版本和完整参数。

这些字段在目录对象中为可选,但 editor 值是受控枚举。注册器和 Schema 当前只支持上述三类;新增编辑器必须成套扩展元数据、校验和前端控件,不能将未知编辑器退化为普通输入作为正式支持。已有型号仍有专用动态端口/迁移逻辑,新增普通参数控件继续以目录为来源。

property_model 是每种介质组件内部的稳定选项编号,不等同于 AMESim 原始 eosType。例如空气组件的 property_model=0 表示理想气体,并映射到 fluidType=2/eosType=1;氦气组件的 property_model=0 表示 Peng-Robinson,并映射到 fluidType=12/eosType=6。编译层负责保存这种映射, 前端只使用目录选项。

前端不再维护内置兜底目录。后端目录不可用时,组件区保持为空,并在“组件库” 标题旁显示红色“加载失败”状态;悬停或聚焦该状态可查看失败范围和详细原因。 experimental 试验库即使由成功的目录响应返回,也不会出现在组件区。

14.1 前端实际读取步骤

React Flow 启动时:

  1. 使用 no-store 请求 /api/components/catalog。
  2. 检查 schemaVersion == 1。
  3. 检查库、模型、端口和参数结构。
  4. 检查模型 type 是否全局重复。
  5. 将参数数组转换为参数面板定义。
  6. 按库、分类和模型的 order 排序。
  7. 过滤仅用于注册验证的 experimental 试验库。
  8. 成功时用绿色状态显示“已加载 X 个组件库”,不追加其他成功说明。
  9. 请求或格式校验失败时显示红色“加载失败”,不显示任何兜底组件;悬停状态可 查看具体库名(目录响应可识别时)或受影响范围、接口地址与错误原因。

14.2 修改后如何生效

修改 Python 模型、库清单或注册器后必须重启 FastAPI:

cd F:\Master\SystemSimulationApp
.\.venv-win\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000

只刷新浏览器无法让已运行的 Python 进程重新导入模型。前端源代码由 Vite 开发服务 热更新;普通目录内容变化不需要重启 Vite。

14.3 目录对象与工程快照不是同一协议

目录经 normalizeComponentCatalog() 转为前端模型定义;工程 JSON 经 parseProjectPayload() 校验后才与当前目录合并。后端能够从 JSON 生成合法 XML,不代表该 JSON 能被浏览器导入。 当前工程连线还必须有 data.isContactEdge 布尔字段,仅有两端点不足以通过浏览器解析。

例如目录中的信号端口可能含 "positiveFlowDirection": null,当前工程解析器仅接受该字段缺省或值为 "intoComponent",因此信号端口快照应省略它:

{"name":"out","kind":"signal","domain":"signal","nominalRole":"output","side":"right"}

人工或脚本生成工程应采用实际浏览器导出的结构,保留节点版本、按对应格式约定存储的参数、布局与真实连线端点;不要原样复制目录端口对象。物理供需规则仍来自注册表,快照不能覆盖它们。导入后检查模型、导出 XML、运行以及再次导出 JSON 都是必要验证。

当前前端要求所有显示端口恰好连接一次。后端独立信号算例可以只有未接端口警告,浏览器会将其视为运行前错误;网页验收须使用完整接线工程。

15. System XML 映射

System XML 中的组件片段如下(仅演示字段结构;实际气瓶还须写全其余声明参数,不能直接将此片段作为有效最小算例):

<Component
  id="cylinder_1"
  type="cylinder"
  modelVersion="1.0.0">
  <Parameter name="volume" value="0.01"/>
</Component>

映射规则:

  • id:工程内唯一的组件实例 ID。
  • type:必须匹配唯一的 MODEL_TYPE。
  • modelVersion:必须与该模型当前 MODEL_VERSION 完全一致。
  • <Parameter name>:必须完整且只能来自模型的 PARAMETERS,数值使用 SI。
  • XML v3 不保存 name/componentType/Port 或画布布局;连接中的 Endpoint/@port 必须存在于模型的 PORTS。

介质定义组件不通过物理端口连接。XML 和前端通过目录角色 amesimGasMediumDefinition 识别,网络构造则通过 AmesimGasMediumDefinitionComponent 基类识别并收集介质定义,再解析带 editor="amesimGasReference" 参数的组件引用;介质定义组件本身不进入数值 仿真网络。System XML 语义校验会在编译前检查介质索引的整数范围、定义唯一 性、正索引引用完整性,以及同一气动连通分量的引用一致性。

XML 解析器只负责结构、引用和契约校验;模型注册中心负责选择 Python 类并创建实例; Python 模型负责声明与约束;原生生成器分配状态、生成方程和输出,公共 C 模块执行数值计算。目录注册不能替代原生实现。

16. 测试要求

每个新模型至少需要:

  1. 元数据测试:模型类型、端口、参数和结果声明合法。
  2. 目录测试:模型出现在正确库和分类中。
  3. 默认创建测试:默认参数能构造模型。
  4. 参数边界测试:非法值被拒绝,错误信息包含组件和参数。
  5. 端口测试:实例端口与声明完全一致。
  6. XML 测试:最小系统能解析并映射到正确模型。
  7. 方程测试:至少验证一个稳态、残差或守恒关系。
  8. 最小仿真测试:一个短时算例能产生有限结果和结构化结果元数据。

库级测试还应检查:

  • 库清单中的所有类均可导入。
  • 所有模型类型全局唯一。
  • 无遗漏或重复分类。
  • GET /api/components/catalog 满足目录 schema。

17. 新增模型操作清单

按注册流程执行以下步骤:

  1. 明确模型依据,列出参数、端口供需、状态、结果和支持边界。
  2. 在目标库声明六个公共字段与类自身的 create(),校验默认值和参数边界。
  3. 加入库清单;新库还需启用列表及原生 catalog_contracts() 入口。
  4. 实现或复用 C 模块,新增导出函数时同步 kernels.h、modules.py 的导出及依赖。
  5. 接入具体生成路径的状态、初始化、方程、输出、事件,核对求值依赖、雅可比与误差尺度;登记原生支持版本。
  6. 完成独立数值对照、错误输入、最小完整网络、构建与缓存检查。
  7. 重启后端,验证浏览器发现、编辑、导入导出、接线、运行、结果保存和 CSV;需要的新图形或交互能力同步实现。
  8. 记录 Windows/Linux 的实际验证状态,交付接入说明与可复现实例。

普通型号通常不改通用 XML 分派、目录列表或参数面板字段;新协议、编辑器、单位及动态端口等按需修改。只通过目录和 XML 校验应标记“已注册”,不能标记“可求解”。

17.1 AI 修改约束

AI 在处理组件库读取任务时必须:

  1. 先确认目标是新增模型、修改模型还是新增库。
  2. 读取当前启用列表和目标库清单。
  3. 只把公开模型加入 library.py/models。
  4. 不通过递归扫描替代显式清单。
  5. 不在前端重新声明后端契约作为正式实现。
  6. 不静默跳过加载失败的模型。
  7. 保留未知 symbol 的通用图标回退能力。
  8. 修改后检查目录响应,并运行注册表和前端构建测试。
  9. 告知用户需要重启 FastAPI。

AI 不应仅因为某个 .py 文件位于组件目录,就假定它是公开模型。公开性的唯一判断 依据是该类是否出现在已启用库的 models 清单中。

18. 当前实现与目标规范的差异

能力 当前状态 目标
库 ID、名称、版本、分类和模型清单 已实现 由各库 library.py 维护
库和模型注册表 已实现 由已启用库清单自动构建
前端目录接口 已实现 已包含库版本和模型版本
前端动态分类和参数读取 已实现 新增已支持图标的模型无需改组件列表
端口与参数契约 已实现 保持为唯一事实来源
结构化结果元数据 已实现 保持为唯一事实来源
DISPLAY 已实现 由公开模型类自行声明
模型工厂 已实现 模型类统一 create()
模型发现 已实现 按库清单受控发现
启动校验 已实现首版 覆盖版本、分类、端口、参数、单位和默认实例
System XML 中的模型版本 已实现 v3 显式保存并严格匹配 modelVersion
工程 JSON 的整体版本 已实现 v2 统一所选单位语义,兼容读取 v1;节点保留来源版本并在兼容导出时更新
自动版本迁移 无通用框架,部分型号有前端专用迁移 JSON 版本差异警告后生成当前 XML,XML 精确匹配;新型号明确语义兼容边界
目录 JSON Schema 已实现 schemas/component-catalog-v1.schema.json

19. 维护与版本同步

新增模型按第 17 节逐层验证,不再把“建立正式库”列为未来任务:amesim 已是启用的公开库。当前目录加载有缓存,修改 Python 声明、清单或原生发现代码后须重启服务。前端发布包有变更时须重新构建;仅刷新页面不会重新导入后端模块。

模型版本修改时同时核对原生支持表、工程/XML 示例和兼容处理。原生内容缓存根据内容和构建环境失效,不以删除用户全部缓存作为新增模型的常规步骤。文档修订版本独立于库版本、模型版本、目录 schema 版本和工程格式版本。

20. 改动影响表

想做的改动 必须修改 通常不需要修改
新增同库同分类模型 模型声明、库清单、原生支持版本、代码生成及数值实现/复用、测试 注册中心启用表、普通前端参数列表
新增分类 库 categories、模型 DISPLAY.category_id、测试 物理端口和求解器
新增组件库 新库包和清单、启用列表、原生 catalog_contracts()、逐型号数值接入和测试 已有库清单
修改参数默认值或范围 模型 PARAMETERS、测试、必要的版本 前端参数硬编码
修改端口 模型 PORTS、DISPLAY.ports、主版本、XML/网络拒绝边界测试 库分类
新增 C 导出函数/模块 数值模块、kernels.h、modules.py 导出/依赖、生成调用、适用的雅可比依赖与测试 前端分类
新增专用图标 模型 DISPLAY.symbol、前端图标渲染器 参数和物理方程
新增物理域 端口协议、网络、求解器、XML、前端兼容规则和测试 仅修改分类名称
修改目录响应结构 后端序列化、JSON Schema、前端解析、协议版本和测试 单个模型方程

21. 读取故障排查

现象 优先检查
模型完全没有出现在目录响应 模型类路径是否加入已启用库的 models
FastAPI 无法启动 启动错误中的库、模型和字段;通常是契约校验失败
接口有模型但前端没有 schemaVersion、目录规范化、库是否为隐藏的 experimental
前端显示红色“加载失败” 悬停状态查看详情,再检查 8000 端口、/api/components/catalog、后端是否重启
分类错误 DISPLAY.category_id 与库 categories
端口数量或位置错误 PORTS 与 DISPLAY.ports 是否完全一致
参数面板缺字段 模型 PARAMETERS 和目录响应,不先改前端
XML 报不支持类型 XML type 是否精确匹配 MODEL_TYPE
导入 JSON 失败但后端 XML 正常 工程解析器要求与目录对象的差异,尤其信号端口的 null 字段
目录可见但原生失败 原生发现入口、支持版本、C 输出映射和模块导出是否逐层齐全
图标是通用图形 symbol 尚无专用前端渲染器,但模型仍应可用

最小诊断命令:

.\.venv-win\Scripts\python.exe -c "from app.simulation.registry import build_component_catalog; print(build_component_catalog())"
.\.venv-win\Scripts\python.exe -m unittest tests.test_component_registry tests.test_component_catalog

22. 本轮代码核对(2026-09-12)

1.1.1 修正了 DISPLAY 介质角色的实际用途、结果可见性和未知编辑器支持边界。工程存储/执行、HTTP/CLI 表达式和网页结果保存差异统一见接口规范,本规范不重复声明一套实现。