嵌入工作流节点表单

A3S Form 可以作为工作流节点设置面板中的表单引擎,不接管宿主产品。宿主拥有节点值和持久化,A3S Form 负责编译、校验与渲染。

固定表单版本

每个节点保存一份配置模式的 FormRef

const form = {
  uri: 'a3s://forms/workflow/llm',
  revision: 7,
  digest: 'sha256:…',
  mode: 'configuration',
};

revisiondigest 防止后续表单发布静默改变已有节点。

解析后的 plan 还包含 schemaProfile: "a3s.dev/form-schema-profile/1"。宿主不支持该 profile 时,必须在渲染节点设置前关闭操作。

保持受控值

import { FormRenderer } from '@a3s-lab/form/react';
import {
  createWorkflowNodeConfiguration,
  validateWorkflowNodeConfiguration,
  verifyPinnedForm,
} from '@a3s-lab/form/workflow';
import { FORM_LOCALE_CATALOG_API_VERSION } from '@a3s-lab/form/core';
import '@a3s-lab/form/styles.css';

const pinned = verifyPinnedForm(document, form);
if (!pinned.ok) throw new Error(pinned.message);

const configuration = createWorkflowNodeConfiguration({
  nodeType: 'llm',
  nodeId,
  form,
  value,
  locale,
  readOnly: !canEdit,
});

const save = async () => {
  const result = validateWorkflowNodeConfiguration(pinned.document, configuration);
  if (!result.ok) {
    setErrors(result.errors);
    return;
  }
  await saveNode({ ...configuration, value: result.value });
};

<FormRenderer
  plan={pinned.plan}
  value={value}
  errors={errors}
  hostAdapter={hostAdapter}
  locale={locale}
  localeCatalog={{
    apiVersion: FORM_LOCALE_CATALOG_API_VERSION,
    messages: { selectPlaceholder: '选择模型' },
  }}
  readOnly={!canEdit}
  onChange={setValue}
  onAction={save}
/>;

是否允许当前用户编辑、值存在哪里、数据源可以读取哪些密钥、操作能否执行,仍由宿主决定。

locale 覆盖属于宿主配置,不写入工作流节点值或表单文档。编译计划会记录字段订阅,因此修改一项设置不会重绘或重新加载无关字段;分页和字段回调仍能拿到最新完整受控值。

行标识留在节点配置之外

对象数组参数可以使用带子字段的 repeater。宿主从 onChange 收到的仍是普通数组,A3S Form 不会加入隐藏行 key。

如果外部状态仓库会重新创建行对象,可以从业务属性推导标识:

const hostAdapter = {
  identifyRepeaterItem({ node, item }) {
    if (node.id !== 'routes' || !item || typeof item !== 'object' || Array.isArray(item)) {
      return undefined;
    }
    return typeof item.route === 'string' ? item.route : undefined;
  },
};

只有 item Schema 本来就包含必填字符串标识时才声明 itemKey。逐行规则和数据源依赖模板按行顺序解析,值结构保持不变。完整协议见重复字段组

CSS 不影响宿主

Form 样式不包含 Tailwind preflight、:root token 或无作用域元素 reset。包检查会限制 120 KB 原始体积和 20 KB gzip 体积,并拒绝影响宿主的全局选择器。

通过类型检查的参考组件位于 examples/workflow-node-settings-host.tsx