1flowbase
← 文档

工程手册

Schema UI 分层:画布节点、系统页面与插件设置页的边界

1flowbase 的 schema UI 不是一个统一的大 DSL。它按使用场景拆成几类协议:画布节点 UI、宿主容器、系统页面内容,以及插件配置表单。这样做的目的,是让插件和页面可以扩展,但不把节点专属语义、系统权限、React 组件实现和后端接口边界混在一起。

快速判断

用户在画布里编辑节点
  -> canvas_node_schema

用户点击按钮打开 Drawer / Modal / Dock
  -> overlay_shell_schema

系统设置页、插件管理页、普通页面区块显示内容
  -> page_block_schema

插件提供一组配置字段,宿主负责渲染和保存
  -> plugin_form_schema

最重要的区分是:

  • canvas_node_schema 是节点专属协议。
  • overlay_shell_schema 是容器外壳协议。
  • page_block_schema 是系统级页面内容协议。
  • plugin_form_schema 是插件配置字段协议,通常被 page block 或 overlay shell 承载。

总体结构

schema-ui runtime
├─ canvas_node_schema
│  └─ Agent Flow 节点卡片、节点详情、节点配置、运行态视图
├─ overlay_shell_schema
│  └─ Drawer / Modal / Dock 这类宿主容器
├─ page_block_schema
│  └─ 设置页、插件页、系统页面里的受控 UI primitive
└─ plugin_form_schema
   └─ 插件声明配置字段,宿主用通用控件渲染

底层 runtime 负责按 schema 找 renderer。当前核心形态是:

  • SchemaRenderer:按 fieldviewdynamic_formsectionstackinlinetabs 渲染 block。
  • RendererRegistry:宿主注册允许使用的 field / view / dynamic form / shell renderer。
  • SchemaAdapter:提供 getValuesetValuegetDeriveddispatch,让 renderer 不直接知道业务状态存在哪里。

canvas_node_schema:画布节点专属

canvas_node_schema 描述 Agent Flow 画布上的节点 UI。它不只是配置表单,而是完整节点 UI 的结构:

canvas_node_schema
├─ card
│  └─ 节点卡片上显示什么
├─ detail
│  ├─ header
│  └─ tabs
│     ├─ config
│     └─ lastRun
└─ runtimeSlots

它可以使用节点上下文,所以可以有很多节点专属 renderer:

  • 上游变量选择器
  • 模板文本输入
  • 数据模型查询条件
  • LLM 模型选择
  • LLM 参数动态表单
  • HTTP request body 编辑
  • if / else 分支配置
  • state write 配置
  • 输出变量定义
  • 节点运行态 summary / input / output / metadata

这些 renderer 依赖节点上下文,例如上游输出、当前节点类型、数据模型字段、运行记录、节点配置对象等。它们不应该暴露给后台设置页或普通第三方插件页面。

适合放在这里的内容

  • 节点卡片上的标题、模型 badge、描述。
  • 节点详情里的 header、config tab、last run tab。
  • 需要读写节点 config / bindings / runtime 的字段。
  • 需要理解 Agent Flow 变量池、边、节点类型或运行状态的 UI。

不适合放在这里的内容

  • 后台设置页 section。
  • 插件安装页、插件配置页。
  • 系统级资源表格。
  • 普通配置表单。
  • 任意第三方自定义 React 控件。

overlay_shell_schema:容器外壳

overlay_shell_schema 只描述一个内容用什么宿主容器打开。它关心的是“怎么出现”,不是“里面渲染什么”。

典型容器:

  • drawer_panel
  • modal_panel
  • dock_panel

它适合表达:

  • 标题
  • 宽度
  • shell 类型
  • 是否关闭时销毁
  • Drawer / Modal 的宿主挂载行为

它不应该表达:

  • 表单字段
  • 表格列
  • 节点变量选择器
  • 插件配置数据结构
  • 后端 API contract

示意:

点击配置按钮
  -> overlay_shell_schema 决定打开 Drawer
  -> Drawer 里面再承载 plugin_form_schema 或 page_block_schema

所以 overlay_shell_schema 是壳层协议,应该保持小而稳定。

page_block_schema:系统级页面内容

page_block_schema 描述系统页面或插件页面里的内容块。它更接近受控低代码 UI primitive,但仍然由宿主控制可用组件和能力。

它适合系统级页面,例如:

  • 后台设置页 section
  • 插件详情页
  • 插件贡献的设置页内容
  • 系统资源列表
  • 简单状态面板
  • 带白名单 action 的按钮区域

可用 primitive 应该是宿主白名单,例如:

  • Stack
  • Inline
  • Grid
  • Divider
  • Text
  • Title
  • Caption
  • Badge
  • Table
  • Descriptions
  • Empty
  • Alert
  • Form
  • FormItem
  • Input
  • Textarea
  • Select
  • Checkbox
  • Switch
  • DatePicker
  • NumberInput
  • Button
  • IconButton
  • Modal

这里的关键不是“让插件写页面代码”,而是让插件声明受控页面内容。宿主仍然负责:

  • primitive 白名单
  • 样式 token 边界
  • action 白名单
  • data permission
  • route / slot 权限
  • 字段 contract
  • 后端数据来源

plugin_form_schema:插件配置字段

plugin_form_schema 是插件配置表单协议。插件可以声明字段,宿主负责渲染、校验、提交和保存。

它适合:

  • 模型供应商插件配置。
  • host infrastructure provider 配置。
  • 后续第三方插件注册到设置页后的配置表单。
  • Drawer / Modal / 页面 section 内的普通设置表单。

建议一期公开的字段类型:

string
number
integer
boolean
enum
json
secret

建议一期公开的 control:

input
textarea
number
slider
switch
select
json_editor
password

字段元数据:

key
label
description
placeholder
required
default_value
group
order
advanced
min
max
step
precision
unit
options
visible_when
disabled_when
send_mode
enabled_by_default

plugin_form_schema 不应该允许插件传入任意 React 组件名。插件只声明字段和规则,控件实现由 1flowbase 维护。

插件注册到设置页时怎么组合

一个插件设置页的推荐组合是:

settings slot
└─ page_block_schema
   ├─ Descriptions:插件状态
   ├─ Table:插件能力或实例列表
   └─ Button:打开配置
      └─ overlay_shell_schema:Drawer
         └─ plugin_form_schema:配置字段

也就是说:

  • 页面上显示什么,用 page_block_schema
  • 弹层怎么打开,用 overlay_shell_schema
  • 弹层里的配置字段,用 plugin_form_schema
  • 如果是画布节点详情,不走这条系统页面协议,而走 canvas_node_schema

边界规则

不能把节点 renderer 暴露给系统页面

这些属于节点语义,不应该进入系统级插件页面:

  • selector
  • selector_list
  • templated_text
  • data_model_query
  • llm_model
  • condition_group
  • if_else_branches
  • state_write
  • output_contract_definition
  • http_request_body

它们依赖 Agent Flow 节点上下文。放到系统页面里,会让页面 schema 偷偷依赖节点运行时。

不能让插件直接提供 React 控件

第三方插件可以提供 schema、字段、选项、默认值和规则,但不直接提供 React 组件。否则会破坏:

  • 宿主 UI 一致性
  • 样式边界
  • 权限边界
  • 前后端 contract
  • 插件安全模型
  • 后续升级兼容性

后端仍是唯一数据来源

前端 schema-ui 负责渲染和交互,不负责发明字段别名、兼容后端旧字段或改变业务语义。接口字段名应与后端 DTO / 领域语义保持一致;UI 展示名可以本地化。

普通 runtime / capability plugin 不能注册系统接口

插件页面注册不等于插件能注册新的系统 API。普通 runtime / capability plugin 只能使用宿主预定义的白名单能力槽位。系统接口扩展必须继续由 host 认可的扩展点控制。

当前实现状态

当前代码里已经有这些基础:

  • web/app/src/shared/schema-ui/runtime/SchemaRenderer.tsx
    • schema runtime。
  • web/app/src/shared/schema-ui/registry/create-renderer-registry.ts
    • renderer registry 和 adapter contract。
  • web/app/src/shared/schema-ui/contracts/canvas-node-schema.ts
    • 画布节点 schema contract。
  • web/app/src/shared/schema-ui/contracts/overlay-shell-schema.ts
    • Drawer / Modal / Dock shell contract。
  • web/app/src/shared/schema-ui/contracts/plugin-form-schema.ts
    • 插件配置字段 contract。
  • web/packages/page-protocol/src/block-ui-schema.ts
    • 系统级 page block primitive contract。
  • web/app/src/features/agent-flow/schema
    • Agent Flow 节点专属 schema fragments 和 renderer registry。

当前还需要继续收敛的部分:

  • plugin_form_schema 的通用表单渲染仍分散在 LLM 参数、模型供应商配置、host infrastructure 配置等不同页面里。
  • 后续应该抽出统一的 PluginSchemaForm,专门服务系统级插件配置。
  • PluginSchemaForm 不应吞并 canvas_node_schema,也不应复用节点专属 renderer。
  • page_block_schema 应继续作为系统页面内容协议推进,和 overlay shell 保持分离。

推荐演进顺序

  1. 固定 schema 名词和边界:节点、容器、页面、插件表单分开。
  2. PluginSchemaForm,统一渲染 plugin_form_schema
  3. 给后台设置页定义 host-controlled slot,例如 settings.sectionsettings.tabsettings.drawer_form
  4. 让第三方插件只能注册 slot contribution 和 schema,不直接注册 React 组件。
  5. 再推进 page_block_schema 的系统页面 renderer,覆盖设置页状态块、表格、描述和白名单 action。

这样分层以后,1flowbase 可以开放第三方插件注册页面,同时保持宿主对 UI、权限、接口、样式和运行时边界的控制。