Activepieces 属性类型(Property Types)完全指南:从基础输入到动态属性与联动下拉
2026/9/12 16:29:34 网站建设 项目流程

Activepieces 属性类型(Property Types)完全指南:从基础输入到动态属性与联动下拉

【免费下载链接】activepiecesAI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces

Activepieces 的每个 action 与 trigger 都通过props声明自己的输入表单,这些属性类型同时服务于两类使用者:构建器界面中的真人用户,以及通过 MCP 协议接入的 LLM Agent。本指南以.agents/skills/piece-builder/props-patterns.md为骨架,结合packages/pieces/framework源码与packages/pieces/community/github真实实现,系统讲解Property.ShortTextProperty.DropdownProperty.DynamicProperties等全部属性类型的语法、底层机制与实战模式。读完你将能够为任意第三方 API 设计出既符合类型约束、又能被 LLM 准确理解的属性表单。

属性描述(description)是 Agent 的唯一信号

description是 LLM/MCP Agent(以及构建器中的用户)决定如何填写属性的唯一依据,它应该是一两句「规格说明」,而不是一个标签:

  • 说明格式,而不仅是概念。"Issue title. Max 255 characters."远胜于"The title"
  • 当格式重要时,把真实的样例直接写进描述文案。例如真实的 ID 形态('cus_abc123xyz')、ISO 8601 日期('2026-04-17T10:30:00Z')、带协议头的完整 URL。属性体系中没有单独的 example 字段,description 承担了全部信号,例如:"Current status of the record. One of: 'open', 'in_progress', 'closed'."
  • 当属性不言自明时可跳过样例(如布尔复选框),或者值来自运行时 API(Property.DropdownProperty.DynamicProperties)。
  • 绝不使用占位符式的空样例——'string''value''<your API key>'、空的{}/[]都毫无信息量。

这条规则在 .agents/skills/piece-builder/SKILL.md 的「UX Quality」一节得到呼应:pieces 的使用者可能是从未接触过 API 的人,描述必须具有教学性,例如不要写「输入线程时间戳」,而要写「点击消息右侧的三个点,选择 Copy Link,粘贴末尾的数字」。

文本、数字与布尔:基础标量类型

最常用的三个基础类型,语法与用途如下:

Property.ShortText({ displayName: 'Title', description: 'Optional help text', required: true, defaultValue: 'Default text', }) Property.LongText({ displayName: 'Body', required: false, })
  • ShortText对应单行输入,适合姓名、邮箱、ID 等短值;
  • LongText对应多行文本域,适合备注、正文等自由长文本;
  • Number接收数值;Checkbox接收布尔值:
Property.Number({ displayName: 'Limit', required: false, defaultValue: 10, }) Property.Checkbox({ displayName: 'Include archived?', required: false, defaultValue: false, })

在源码层面,这些类型分别对应 text-property.ts、number-property.ts 与 checkbox-property.ts,它们共享 common.ts 中的BasePropertySchema(包含displayNamedescriptionrequireddefaultValue等公共字段)。

日期时间与文件

Property.DateTime({ displayName: 'Due Date', required: false, }) Property.File({ displayName: 'Attachment', required: false, })

DateTime表示一个时间瞬间(对应 date-time-property.ts);File在运行时解析为ApFile对象(见 file-property.ts)。如果需要「时间窗口」(如最近 7 天),应改用Property.DateRange,在run()中通过dateRangeUtils.resolve(context.propsValue.date_range)解析出{ after, before }ISO 字符串——这是搜索/筛选类 action 的标准做法,详见 property-ui-selection.md 的显示增强章节。

JSON、Object 与 Array

结构化数据的三种形态:

Property.Json({ displayName: 'Custom Data', description: 'Enter valid JSON', required: false, }) Property.Object({ displayName: 'Metadata', description: 'Key-value pairs', required: false, }) // Simple array of strings Property.Array({ displayName: 'Tags', required: false, }) // Array with structured sub-properties Property.Array({ displayName: 'Line Items', required: true, properties: { name: Property.ShortText({ displayName: 'Item Name', required: true }), quantity: Property.Number({ displayName: 'Quantity', required: true }), price: Property.Number({ displayName: 'Price', required: false }), }, })

要点:Json只应在没有更好的结构化选项时使用(对应 json-property.ts);Object提供字典编辑器(object-property.ts);Array不带properties时是纯字符串列表(标签、邮箱),带properties时则渲染为可重复的记录编辑器(如订单行项目),底层实现见 array-property.ts。

静态下拉:预定义选项

Property.StaticDropdown({ displayName: 'Status', required: true, options: { options: [ { label: 'Active', value: 'active' }, { label: 'Inactive', value: 'inactive' }, { label: 'Archived', value: 'archived' }, ], }, }) Property.StaticMultiSelectDropdown({ displayName: 'Categories', required: false, options: { options: [ { label: 'Sales', value: 'sales' }, { label: 'Marketing', value: 'marketing' }, ], }, })

静态下拉适用于选项在编码期就完全确定的场景,定义于 static-dropdown.ts。对于 2~4 个互斥模式,可以附加display: 'cards'让每个选项以「图标 + 一行说明」的形式呈现;StaticDropdowndefaultValue应设为选项中的某个合法值,以便首屏直接渲染。

动态下拉:从 API 拉取选项

动态下拉是「绝不让用户手输 ID」这一铁律的标准答案——用户按名称选择,值传 ID。完整模式:

Property.Dropdown({ displayName: 'Project', auth: myAppAuth, refreshers: [], // Array of prop names this depends on required: true, options: async ({ auth }) => { if (!auth) { return { disabled: true, options: [], placeholder: 'Please connect your account first' }; } const response = await httpClient.sendRequest<{ data: { id: string; name: string }[] }>({ method: HttpMethod.GET, url: 'https://api.example.com/v1/projects', authentication: { type: AuthenticationType.BEARER_TOKEN, token: auth.secret_text }, }); return { disabled: false, options: response.body.data.map((item) => ({ label: item.name, value: item.id, })), }; }, })

两条必须遵守的硬规则

始终传auth每一个Property.DropdownProperty.MultiSelectDropdownProperty.DynamicProperties,只要其options/props回调读取了auth,就必须设置auth: <pieceAuth>(例如auth: myAppAuth)。否则回调里的authundefined,下拉永远加载不出来。从src/lib/*相对路径导入 auth 对象(import { myAppAuth } from '../auth'),绝不要从src/index.ts的再导出导入。真实范式见 github/src/lib/common/index.ts。

无需类型断言——auth已自动推断类型。设置auth: myAppAuth一举两得:既让回调拿到auth,又告诉 TypeScript 连接类型。框架仅用该auth字段推断类型,因此回调内auth.secret_text(SecretText)、auth.access_token(OAuth2)、auth.props.<field>(CustomAuth)都是正确类型,直接读取即可。永远不要写auth as { secret_text: string }之类的断言——仓库明令禁止,且纯属冗余。无断言的真实案例见airtablebaremetricstodoist的 common 文件。

源码层面,auth字段被明确注释为「用于推断 PieceAuth 类型的 dummy 属性」,见 dropdown-prop.ts 与 dynamic-prop.ts。

联动下拉:父属性变化时刷新

当某个下拉的选项依赖另一个属性的值(如先选项目、再选项目下的任务)时,使用refreshers声明依赖:

Property.Dropdown({ displayName: 'Task', refreshers: ['project'], // Re-fetches when 'project' prop changes required: true, auth: myAppAuth, options: async ({ auth, project }) => { if (!auth || !project) { return { disabled: true, options: [], placeholder: 'Please select a project first' }; } const response = await httpClient.sendRequest<{ data: { id: string; name: string }[] }>({ method: HttpMethod.GET, url: `https://api.example.com/v1/projects/${project}/tasks`, authentication: { type: AuthenticationType.BEARER_TOKEN, token: auth.secret_text }, }); return { disabled: false, options: response.body.data.map((item) => ({ label: item.name, value: item.id })), }; }, })

refreshers: ['project']表示当名为project的属性变化时重新执行options回调,回调参数中会带上该项目名对应的当前值。前置条件未满足时返回disabled: true并给出有引导性的placeholder(「Please select a project first」而非留空)。真实实现可查看 GitHub piece 的repositoryDropdownissueDropdownlabelDropDown——它们正是「仓库 → 议题 → 标签」三级联动的范例,见 github/src/lib/common/index.ts。

动态多选下拉

Property.MultiSelectDropdown({ displayName: 'Labels', refreshers: ['repository'], required: false, auth:myAppAuth, options: async ({ auth, repository }) => { // Same pattern as Dropdown, returns multiple selected values }, })

模式与Dropdown完全一致,区别在于返回值是多个选中值组成的数组。其类型定义位于 dropdown-prop.ts,TPropertyValue<T[], ...>表明运行时值是一个数组。

动态属性:字段在运行时才确定

当表单字段本身来自 API(例如自定义表格的列)时,用DynamicProperties在运行时构建子表单:

Property.DynamicProperties({ displayName: 'Record Fields', refreshers: ['tableId'], required: true, auth: myAppAuth, props: async ({ auth, tableId }): Promise<DynamicPropsValue> => { if (!auth || !tableId) return {}; const fields = await fetchTableFields(auth, tableId); const properties: DynamicPropsValue = {}; for (const field of fields) { properties[field.id] = Property.ShortText({ displayName: field.name, required: field.required, }); } return properties; }, })

底层实现见 dynamic-prop.ts:DynamicPropsValueRecord<string, DynamicProp>,而DynamicPropShortTextStaticDropdownJsonArrayStaticMultiSelectDropdown五种类型的联合(第 11-25 行)——也就是说,动态属性内部可以嵌套这些受限的属性类型。这是最重的组件,只有当字段形态真正依赖运行时数据时才使用。

动态属性作为来源选择器:互斥输入

当用户必须在两种互斥的输入方式之间选择(上传文件 vs S3、URL vs 文件等)时,用「StaticDropdown选择器 +DynamicProperties联动」组合:

source: Property.StaticDropdown({ displayName: 'File Source', description: 'Choose how to provide the file.', required: true, defaultValue: 'file', options: { options: [ { label: 'Upload a file', value: 'file' }, { label: 'From S3 bucket', value: 's3' }, ], }, }), document: Property.DynamicProperties({ auth: myAppAuth, displayName: 'File', required: true, refreshers: ['source'], // IMPORTANT: explicit Promise<DynamicPropsValue> return type is required // for the UI to re-render when the source selector changes. props: async ({ source }): Promise<DynamicPropsValue> => { if (source === 's3') { return { s3Bucket: Property.ShortText({ displayName: 'S3 Bucket', required: true, }), s3Key: Property.ShortText({ displayName: 'S3 File Path', required: true, }), }; } return { file: Property.File({ displayName: 'File', required: true, }), }; }, }),

规则清单

  • 始终显式声明Promise<DynamicPropsValue>返回类型——没有它,UI 不会在选择器切换时重新渲染;
  • 每个分支直接返回对象字面量——不要先构建可变对象再条件赋值;
  • 所有分支之后以兜底return {}结尾
  • 直接比较选择器值source === 's3')——不需要as unknown as string之类的断言;
  • StaticDropdown上设置defaultValue,保证首次加载即渲染第一个分支。

在 run() 中读取值

const file = source === 'file' ? document['file'] : undefined; const s3Bucket = source === 's3' ? (document['s3Bucket'] as string) : undefined; const s3Key = source === 's3' ? (document['s3Key'] as string) : undefined;

Markdown:纯展示,不收集输入

Property.MarkDown({ value: '## Instructions\n1. Go to Settings\n2. Copy your API key', })

用于设置步骤说明、警告信息或 Webhook URL 展示。判断何时使用它,可参考 ux-guidelines.md(复杂设置的 Markdown 引导是 UX 质量规则之一:当某个属性需要在第三方应用里预先配置时,用带编号步骤的Property.MarkDown())。

属性类型的选型与更完整决策树

本指南专注属性类型的「语法」;「该用哪个组件、加什么显示增强、如何分组」的完整决策树见 property-ui-selection.md:包括display: 'cards'/'stepper'RichText+formatPropertyCheckboxreveals渐进披露、propertyGroupstabs/section/builder/footer四种布局,以及合法的icon名称列表。而createPiece({ categories: [...] })所需的PieceCategory取值不属于属性类型范畴,统一收录在 piece-types.md。所有类型的渲染预览可见 docs/build-pieces/piece-reference/properties.mdx。

总结

Activepieces 属性体系以「描述即信号」为设计哲学:每个属性既要在构建器中呈现为可用的输入控件,也要向 LLM Agent 传达填写所需的一切上下文。从静态标量到动态下拉、再到可重渲染的动态属性组合,类型系统通过refreshersauth推断与DynamicPropsValue的联合约束,在编码期保证了表单的运行时正确性。遵循本指南的规则——传auth、不写断言、显式返回类型、描述含真实样例——即可写出对人和 Agent 都友好、且通过 CI 构建与 lint 的 piece 属性。

【免费下载链接】activepiecesAI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询