AIButton 开发规范
本文档描述
AIButton组件的使用规范、可传入参数以及编排模式的设计原理。 适用于在 WeGirl Office 各插件/面板中新增「AI 行动按钮」的场景。
更名说明(2026-09-14):组件
SparkleButton已更名为AIButton(原名难理解)。@wegirl/sdk仍导出SparkleButton兼容别名(旧插件 bundle 不受影响),新代码一律使用AIButton。 内部约定不变:sparkleFor属性名、sparkleMeta会话元数据、sparkle-button-configs.json持久化文件均保持原名(兼容存量配置与跨项目调用方)。 本文档原文件名SPARKLE_BUTTON_SPEC.md。
1. 组件定位
AIButton 是一个可配置的 AI 行动按钮:
- 点击后唤起统一的
SparkleAiRunModal运行窗口; - 每次点击都会新建一个会话(长任务/短任务),不复用已有会话;
- 编排(DSL)与变量在点击时绑定到会话的
sparkleMeta,用户在聊天框点击「发送」即触发 AI 运行; - 按钮配置按
projectId + sparkleId持久化到~/.wegirl-office/wegirl-office.db(kv 表,key=sparkle_button_configs;2026-09-14 起取代旧sparkle-button-configs.json文件,宿主首次启动自动导入并备份原文件)。
典型使用场景:
- 产品库「✨ 智能创建产品」
- 邮件详情「✨ 智能回复」
- 任何需要「一键唤起特定编排并传入上下文变量」的入口
2. 参数规范
import { AIButton } from '@wegirl/sdk'; // 或通过宿主暴露的共享组件引入
<AIButton
id="cross-border-create-product" // 必填:唯一标识,用于持久化配置
sparkleFor="product-creator" // 必填:分组名,决定可用编排列表
project={project} // 必填:当前项目对象,需包含 id / path
title="智能创建" // 可选:按钮文案,默认 "AI 运行"
variables={{ subject: '...' }} // 可选:传入编排的变量对象
onResult={(result) => { ... }} // 可选:用户「采用」最终结果后的回调
theme="dark" // 可选:主题
orchestrations={[...]} // 可选:限制可选编排列表
defaultPrompt="..." // 可选:预填到聊天输入框的提示词模板
tempSessionName="..." // 可选:新建会话名称模板
/>
2.1 必填参数
| 参数 | 类型 | 说明 |
|---|---|---|
id |
string |
按钮唯一标识。同一项目内不同按钮必须不同,否则配置会互相覆盖。 |
sparkleFor |
string |
分组名。限定配置弹窗中可选的编排范围,并在无保存配置时作为默认推导依据。 |
project |
object |
当前项目对象,至少包含 id 与 path。 |
2.2 可选参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title |
string |
"AI 运行" |
按钮显示的文案。 |
variables |
object |
{} |
传给编排的变量集合,可在 defaultPrompt / tempSessionName 中用 {{key}} 引用。 |
onResult |
(result) => void |
— | 用户在 SparkleAiRunModal 点击「采用此结果」后触发。 |
theme |
"dark" | "light" |
系统主题 | 按钮与配置弹窗的主题。 |
orchestrations |
Array<{id, name, dsl}> |
null |
若传入,则配置弹窗只从该列表中选择,不从全局 store 拉取。 |
defaultPrompt |
string | (variables) => string |
null |
打开运行窗口后预填到聊天输入框的内容。支持 {{key}} 模板插值或函数返回。 |
tempSessionName |
string | (variables) => string |
null |
新建临时/长任务会话的名称模板。默认「回复:【{{subject}}】」或「短任务/长任务」。 |
3. 运行流程
点击主按钮后,AIButton 内部按以下顺序执行:
- 生成 requestId 并注册
onResult回调(如果传入)。 - 解析编排:
- 优先使用用户在配置弹窗中保存的
orchestrationId; - 若未保存配置,则按
sparkleFor在「内置编排 + 项目编排」中匹配第一个可用编排。
- 优先使用用户在配置弹窗中保存的
- 新建会话:
- 配置为「长任务」
__long__→ 创建普通持久会话; - 配置为「短任务」
__short__(默认)→ 创建临时会话,关闭后自动清理。
- 配置为「长任务」
- 绑定 sparkleMeta:把
variables、dsl、orchestrationId、requestId写入会话级sparkleMetaBySession。 - 预填输入:若传了
defaultPrompt,将其渲染后写入会话输入框。 - 唤起
SparkleAiRunModal:用户在聊天框点击发送,handleSendMessage自动从sparkleMeta中读取编排与变量并执行 DSL。
4. 配置持久化
每个 AIButton 都有一个 ⚙️ 配置按钮,点击打开 SparkleConfigModal。
配置内容:
{
"sessionId": "__long__" | "__short__",
"sessionName": "长任务" | "短任务",
"orchestrationId": "pluginId::编排名" | "__default__",
"orchestrationName": "编排显示名"
}
持久化文件:~/.wegirl-office/sparkle-button-configs.json
{
"<projectId>": {
"<sparkleId>": { "sessionId": "__short__", "orchestrationId": "products-orch::智能创建产品" }
}
}
首次使用未配置时,按钮会按
sparkleFor自动推导默认编排并新建临时会话,保证开箱即用。
5. 编排模式设计
5.1 sparkleFor 分组匹配
sparkleFor 声明在编排文件自身(*.orch.json)的顶层,不再读取插件 plugin.json 的 manifest。
编排的发现也不依赖 manifest.category:任何已安装插件目录里含 *.orch.json 即被加载,编排身份由文件自身决定。
{
"name": "智能创建产品",
"sparkleFor": {
"product-creator": ["智能创建产品"]
},
"tabs": { ... }
}
sparkleFor 支持三种格式:
| 格式 | 示例 | 匹配规则 |
|---|---|---|
| 字符串 | "product-creator" |
分组名等于该字符串即匹配。 |
| 数组 | ["btn-a", "btn-b"] |
分组名在数组中即匹配。 |
| 对象 | {"product-creator": ["智能创建产品"]} |
分组名命中 key,且编排文件名/ID 属于该数组。 |
匹配优先级:
- 用户保存配置中的
orchestrationId; - 按
sparkleFor匹配到的第一个内置编排; - 按
sparkleFor匹配到的第一个项目级编排; - 兜底默认编排(仅当未限定
sparkleFor时)。
5.2 编排 ID 规则
- 默认编排:
__default__ - 内置编排插件:
<pluginId>::<文件名去 .orch.json>,例如products-orch::智能创建产品 - 项目级编排:
<projectId>::<编排 ID> - 同项目兼容:旧数据可能只存
<编排 ID>,运行时会回退到当前项目。
5.3 DSL 运行方式
AIButton 支持两种编排运行方式:
- orchestrationId 模式:只存编排 ID,运行时从 store/磁盘实时读取最新 DSL。
- DSL 内联模式:通过
orchestrationsprop 直接传入{ id, name, dsl },DSL 对象会写入sparkleMeta.dsl,无需 store 查找。
运行时,handleSendMessage 按以下顺序解析 DSL:
sparkleMeta.dsl > orchestrationId 对应的内置/项目编排 > 默认编排
5.4 长任务 vs 短任务
| 模式 | 会话类型 | 项目树节点 | 适用场景 |
|---|---|---|---|
长任务 __long__ |
普通持久会话 | 保留,可再次打开 | 需要持续跟进、结果需要归档 |
短任务 __short__ |
临时会话 | 关闭后自动移除 | 一次性操作,如智能回复、快速生成 |
5.5 变量与提示词模板
variables 中的变量可在以下两个模板中使用 {{key}} 插值:
defaultPrompt:预填到聊天输入框;tempSessionName:新建会话的名称。
示例:
<AIButton
sparkleFor="email-reply"
variables={{ subject: '订单确认', sender: '客服' }}
defaultPrompt="请帮我写一封回复 {{sender}} 关于「{{subject}}」的邮件"
tempSessionName="回复:【{{subject}}】"
/>
也支持函数形式:
defaultPrompt={(vars) => `请回复:${vars.subject}`}
6. 使用示例
6.1 最小可用示例
<AIButton
id="my-feature-run"
sparkleFor="my-feature"
project={project}
title="运行"
/>
6.2 传入变量与结果回调
<AIButton
id="product-create"
sparkleFor="product-creator"
project={project}
title="智能创建"
variables={{ category: '家居' }}
onResult={(result) => {
if (result?.output) {
console.log('AI 生成结果:', result.output);
}
}}
/>
6.3 限制可选编排
const orchs = [
{ id: 'custom-1', name: '自定义编排 A', dsl: dslA },
{ id: 'custom-2', name: '自定义编排 B', dsl: dslB }
];
<AIButton
id="limited-run"
sparkleFor="custom-group"
project={project}
orchestrations={orchs}
/>
7. 开发注意事项
id必须唯一。建议采用<场景>-<动作>命名,如cross-border-create-product、email-reply。sparkleFor必须存在。不允许无分组的AIButton,调用方必须确保对应编排插件声明了相同的分组名。- 不要假设用户已保存配置。首次点击应能直接运行,因此编排插件要提供匹配
sparkleFor的默认编排。 onResult只在用户点击「采用此结果」后触发。若用户关闭窗口或忽略结果,不会触发回调。- 变量命名保持统一。
defaultPrompt与编排 DSL 中使用的变量名应一致,避免运行时变量缺失。 - 临时会话不保留节点。短任务适合一次性操作,不要把需要后续查看的结果放在短任务中。
- 如需自定义按钮 UI,仍需调用
aiRunStore.open。AIButton只是标准封装,业务侧也可以直接调用aiRunStore.open({ sessionId, title })唤起运行窗口。
8. 相关文件
src/components/shared/AIButton/AIButton.jsx— 按钮主组件src/components/shared/AIButton/SparkleConfigModal.jsx— 配置弹窗src/services/sparkleConfigService.js— 配置持久化src/services/orchestrationService.js— 编排加载与sparkleFor解析src/stores/aiRunStore.js— 运行窗口状态管理src/components/desktop/SparkleAiRunModal/SparkleAiRunModal.jsx— 运行窗口 UIsrc/hooks/useDesktopDashboard.js—handleSendMessage中消费sparkleMeta