# 模型 Schema：`properties` / `config` / `rules` / `modeType`

下文只解释 **单模型 `schema` 对象**里各块字段的含义、**`modeType.items` 如何限制入边数量**，以及 **顶层 `rules` 的校验逻辑**。

---

## 1. `properties` — 参数定义（含控件与特殊键）

`properties` 是 **`Record<string, PropertyLike>`**：每个 **key** 对应一类可调参数或一类能力描述；**value** 多为对象，描述如何展示、默认值、合法取值等。

### 1.1 常见「参数项」子字段（value 为对象时）

| 子字段                          | 含义                                                                                                             |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **`displayName`**               | 面板上展示的名称（如「比例」「清晰度」）。                                                                       |
| **`default`**                   | 默认值；`switch` 上常见 `0` / `1`。                                                                              |
| **`enum`**                      | 可选值：字符串/数字，或 `{ value, displayName }[]`。                                                             |
| **`component`**                 | 控件类型，如 `singleButton`、`switch`、`slider`、`input`。                                                       |
| **`originalField`**             | 写入 **`params.settings` / `params.advancedSettings`** 时使用的**键名**；不写则通常与 `properties` 的 key 一致。 |
| **`min` / `max` / `step`**      | 用于 `slider` 等数值范围。                                                                                       |
| **`placeholder` / `maxLength`** | 常用于 **`prompt`** 等文本输入。                                                                                 |
| **`tips`**                      | 辅助说明文案。                                                                                                   |

### 1.2 与 `config` 的关系（谁出现在设置面板里）

- 被 **`config.settings`** 或 **`config.advancedSettings`** 列出的 key，才会进对应「基础设置 / 高级设置」区域（如 `ratio`、`resolution` 走 `settings`，`search_enabled` 走 `advancedSettings`）。
- **`prompt`、`count`、`modeType`** 等往往**不**出现在 `config` 里，而由生成器专用组件直接读 `properties` 里的同名定义。

### 1.3 常见顶层 key（与模态相关）

| key                                                       | 含义摘要                                                                          |
| --------------------------------------------------------- | --------------------------------------------------------------------------------- |
| **`prompt`**                                              | 提示词输入的 UI 元数据；真实内容在节点 **`params.prompt`**。                      |
| **`count`**                                               | 批量条数，多为**数组**（如 `[1,2,4]`），表示可选张数/条数。                       |
| **`modeType`**                                            | 见 **§2**：声明各**逻辑输入模态**及对应的 **`[min,max]`** 入边数量。              |
| **`magic` / `mention` / `portrait` / `cameraControl` 等** | 布尔或简单标记，表示是否开启某类交互或能力（与顶层 **`rules`** 无直接对应关系）。 |
| **`template` / `styles` / `lora` 等**                     | 风格、模板、LoRA 等：`maxCount`、选项等。                                         |

### 1.4 嵌套的 `rules`（例如某 property 下的 `rules`）

部分 **`properties` 内部**会出现名为 **`rules`** 的数组（如营销、划线价条件），语义由**该 property / 业务模块**自行解释，**不是**下文 **§4 顶层 `rules`**。不要与顶层 **`schema.rules`** 混用。

---

## 2. `properties.modeType` — 限制逻辑与各枚举含义

### 2.1 结构

典型形态：

```json
"modeType": {
  "originalField": "modeType",
  "items": {
    "image2video": [1, 9],
    "image2text": [0, 7]
  }
}
```

| 字段 / 取值              | 含义                                                                                            |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| `items`                  | 对象；**key** = 一种**逻辑输入模态**（字符串枚举）；**value** = `[minCount, maxCount]` 二元组。 |
| `items.<mode>[0]`（min） | 该模态下至少需要多少条（例如图生视频至少 1 张参考图）。                                         |
| `items.<mode>[1]`（max） | 该模态下最多允许多少条（**连线数量上限**、多选入边等常读此上界）。                              |
| `[0, 0]`                 | 常表示该模态下**不接收**或**不统计**该类输入（以具体模型与客户端实现为准）。                    |

**语义**：**在当前节点选中的 `params.modeType` 下**（或图片侧由「是否有参考图」推导出的等效模态），从画布上游汇总进 `params` 里某类媒体列表（如 `imageList` / `videoList` / `audioList`）时，该类列表的条数必须落在 `[min, max]`（含端点）。

部分视频模型在 `modeType` 旁还有 **`mixed2videoConfig`**（如 `imageMax` / `videoMax` / `audioMax`），用于 **全能参考**等更细的跨列表上限，与 **`items.mixed2video`** 等配合使用；更复杂的跨 list 约束也可能单独成段配置，以各模型下发的 JSON 为准。

### 2.2 视频（`modality: video`）里常见的 `items` key

| `items` key             | 含义（逻辑输入模态）                                                                   |
| ----------------------- | -------------------------------------------------------------------------------------- |
| **`text2video`**        | 文生视频：主要依赖文案，通常对「参考图/参考视频」条数给 `[0,0]` 或较低上限。           |
| **`singleImage2video`** | 单图参考：参考图数量常为 `[1,1]`。                                                     |
| **`frames2video`**      | 首尾帧：常为 `[1,2]` 或 `[2,2]`（首帧 + 尾帧）。                                       |
| **`image2video`**       | 多图参考视频：参考图为 `[min,max]`。                                                   |
| **`video2video`**       | 参考视频驱动：参考视频条数范围。                                                       |
| **`videoEdit2video`**   | 在已有视频上编辑。                                                                     |
| **`audio2video`**       | 音频驱动/数字人等：音频（及可能绑定的图）条数范围。                                    |
| **`mixed2video`**       | 全能参考：图+视频等混合输入；常与 **`mixed2videoConfig`** 等一起约束总数与各类型上限。 |

未在 **`items`** 里声明的 modeType，一般表示当前模型**不支持**该输入路径（或客户端不提供该选项），具体以产品实现为准。

### 2.3 图片（`modality: image`）

| `items` key       | 含义                                                                                                    |
| ----------------- | ------------------------------------------------------------------------------------------------------- |
| **`image2image`** | 图生图：有上游参考图时的模态；`[min,max]` 约束 **`imageList`** 条数（如 `[0,7]` 表示最多 7 张参考图）。 |

无参考图时，产品侧常等效为 **文生图**（`text2image`），不一定在 `items` 里单独占一行；是否写出 `text2image` 以各模型 metadata 为准。

### 2.4 文本（`modality: text`）

| `items` key      | 含义                                                         |
| ---------------- | ------------------------------------------------------------ |
| **`image2text`** | 图→文：约束汇入 **`imageList`** 的条数上界（如 `[0,7]`）。   |
| **`video2text`** | 视频→文：约束汇入 **`videoList`** 的条数上界（如 `[0,1]`）。 |

### 2.5 音频（`modality: audio`）

很多音频模型 **只有** `prompt`、`instrumental` 等 **`properties`**，**没有** `modeType.items`：入边/媒体条数不由该结构表达，而依赖 **`rules`** 与画布连接规则。

---

## 3. `config` — 设置区布局与任务映射

| 字段                   | 含义                                                                                                                                                                                                                                |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`settings`**         | **基础设置区**要展示哪些参数：值为 **`properties` 的 key 列表**。可以是 **`string[]`**（所有 `modeType` 共用一套 key），也可以是 **`Record<modeType, string[]>`**（按当前 **`params.modeType`** 切换不同 key 列表，视频模型常见）。 |
| **`advancedSettings`** | **高级设置区**的 key 列表，格式与 `settings` 相同。                                                                                                                                                                                 |
| **`generateTypes`**    | 创建生成任务时与 **`taskType` / checkpoint** 等相关的数值映射（`text` / `image` / `audio` / `checkpointId` 等）；**不**用于画布连线条数判断。                                                                                       |

`generateTypes` 为空对象 **`{}`** 或 **`[]`** 等退化形态时，以线上解析逻辑为准；与「是否展示某设置项」无直接对应关系。

---

## 4. 顶层 `rules` — 校验逻辑

顶层 **`schema.rules`** 为**对象数组**，用于判断**当前是否允许发起一次生成**（如生成按钮是否可点）。求值时会把 **`params`** 与上游汇入的 **`textList` / `imageList` / `videoList` / `audioList`** 等整理成一组布尔条件（是否有提示词、是否有图/视频/音频等），再逐条套用规则。

### 4.1 单条规则的字段

| 字段               | 含义                                                                                                    |
| ------------------ | ------------------------------------------------------------------------------------------------------- |
| **`require`**      | 需要的输入类型数组，元素为 **`prompt` \| `image` \| `video` \| `audio` \| `media`** 之一。              |
| **`mode`**         | **`all`**（默认）：`require` 中**每一项**都要满足；**`any`**：`require` 中**至少一项**满足即可。        |
| **`forModeTypes`** | 可选；非空时，仅当当前 **`params.modeType`** 在该数组内，本条规则才参与判断；否则本条视为**直接通过**。 |
| **`message`**      | 可选；不满足时的自定义提示；省略则由客户端按 `require` + `mode` 生成默认中文说明。                      |

### 4.2 多条规则之间的关系

- **规则与规则之间：逻辑 AND**。必须**每一条**都通过，整体才允许生成。
- 对单条规则内部：`require` 内各元素由 **`mode`** 决定是 **AND**（`all`）还是 **OR**（`any`）。

### 4.3 `require` 各类型在上下文里代表什么（典型）

| 类型                  | 何时视为满足（典型约定）                                                                                                                 |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **`prompt`**          | **`params.prompt`** 去掉空白后有内容，或上游文本汇入中存在非空内容；另有镜头聚焦等少数特例会把「无字提示」仍视为满足，以客户端实现为准。 |
| **`image`**           | 存在有效参考图输入（含部分场景/聚焦等特例）。                                                                                            |
| **`video` / `audio`** | 对应列表非空。                                                                                                                           |
| **`media`**           | **图片或视频或音频**任一存在（宽义「有素材」）。                                                                                         |

### 4.4 与「默认规则」的关系

| `schema.rules` 状态     | 行为                                                                                                     |
| ----------------------- | -------------------------------------------------------------------------------------------------------- |
| **不存在 `rules` 字段** | 客户端按**生成器类型**套用内置默认规则（例如图片生成器常见默认：「`prompt` 与 `media` 至少满足其一」）。 |
| `rules: []`（空数组）   | **显式无约束**，不再套用默认规则。                                                                       |
| `rules: [...]` 非空     | **只**使用数组内合法规则项（非法项通常会被过滤并忽略，不中断求值）。                                     |

### 4.5 示例（与常见线上配置一致）

**音频（仅要提示词）**

```json
"rules": [{ "require": ["prompt"] }]
```

**视频（先要「提示词或媒体」其一；在文生视频下还要提示词）**

```json
"rules": [
  { "require": ["prompt", "media"], "mode": "any" },
  { "require": ["prompt"], "forModeTypes": ["text2video"] }
]
```

求值理解：第二条在 **`text2video`** 下额外要求必须有 **`prompt`**；第一条保证整体上不能「既无提示词也无任何媒体」（在 **`media`** 的语义下）。

**图片（两条叠加时常等价于「必须有 `prompt`」）**

```json
"rules": [
  { "require": ["prompt", "media"], "mode": "any" },
  { "require": ["prompt"] }
]
```

第一条：`prompt` 与 `media` **二选一**即可；第二条：**始终**要 `prompt`。合在一起时，仅有上游媒体、**没有**提示词/文本，仍不满足第二条。

---

## 5. `modeType.items` 与顶层 `rules` 的分工（对照记忆）

| 机制                                  | 主要回答的问题                                                                                                                      |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| **`modeType.items[key] = [min,max]`** | 在某个**输入模态**下，某类**媒体列表最多/最少几条**（偏**数量与能力**）。                                                           |
| **顶层 `rules`**                      | 在已有 **`params` + 汇入数据** 的前提下，**是否允许发起生成**（偏**提示词与媒体有无**的组合，可用 **`forModeTypes`** 按模态收紧）。 |

二者可同时存在：连线/入边数量先看 **`items`** 是否超限；能否生成再看 **`rules`**。
