Script
本文档规定了脚本扩展,这是一个灵活的数据层解决方案,通过多个执行上下文实现可扩展功能。脚本扩展为数据处理工作流程中的自定义逻辑执行提供了统一的接口。
支持的脚本类型包括:
- LLM 工具:作为 AI 代理的可调用工具
- 表格动作:在表格记录上触发的自定义动作
- 文档动作:在文档上触发的智能处理
- 文件动作:后台处理文件的一键操作
- 用户自定义函数 (UDF):可在 SQL 查询中调用的数据库函数
脚本扩展通过提供一个标准化框架来在多个上下文中执行自定义逻辑,满足了可扩展数据处理功能的需求。本规范定义了每种支持的脚本类型的元配置结构和执行模式。
2. 脚本类型和规范
Section titled “2. 脚本类型和规范”2.1 LLM 工具脚本
Section titled “2.1 LLM 工具脚本”2.1.1 概述
Section titled “2.1.1 概述”当 type 属性设置为 "tool" 时,脚本作为大型语言模型 (LLM) 工作流程中的可调用工具,使 AI 代理能够执行具有结构化输入/输出模式的自定义函数。
2.1.2 元配置
Section titled “2.1.2 元配置”interface ToolMeta { type: "tool" funcName: string tool: { name: string description: string inputJSONSchema: JSONSchema outputJSONSchema: JSONSchema }}2.1.3 实现示例
Section titled “2.1.3 实现示例”export const meta = { type: "tool", funcName: "hello", tool: { name: "hello", description: "这是一个 hello world 块", inputJSONSchema: { type: "object", properties: { name: { type: "string", }, }, }, outputJSONSchema: { type: "string", }, },}
export function hello({ name }: { name: string }) { return `Hello, ${name}!`}2.2 表格动作脚本
Section titled “2.2 表格动作脚本”2.2.1 概述
Section titled “2.2.1 概述”当 type 属性设置为 "tableAction" 时,脚本作为表格级动作,可以在选定记录上触发。这些动作通过上下文菜单访问,使用自定义功能扩展表格界面。
2.2.2 元配置
Section titled “2.2.2 元配置”interface TableActionMeta { type: "tableAction" funcName: string tableAction: { name: string description: string }}2.2.3 执行上下文
Section titled “2.2.3 执行上下文”表格动作函数接收两个参数:
input: 作为Record<string, any>的选定记录数据ctx: 包含tableId、viewId、rowId和env的上下文对象
2.2.4 实现示例
Section titled “2.2.4 实现示例”export const meta = { type: "tableAction", funcName: "toggleChecked", tableAction: { name: "切换选中状态", description: "切换选定记录的选中状态", },}
export async function toggleChecked( input: Record<string, any>, ctx: { tableId: string viewId: string rowId: string }) { const { tableId, viewId, rowId, env } = ctx console.log(env.MY_SECRET) // 获取环境变量 await eidos.currentSpace.table(tableId).rows.update(rowId, { checked: !input.checked, }) return { success: true, }}2.3 文档动作脚本
Section titled “2.3 文档动作脚本”2.3.1 概述
Section titled “2.3.1 概述”当 type 属性设置为 "docAction" 时,脚本作为文档级动作,可以在特定文档上触发。这些动作通过文档动作菜单访问,让您的文档变得更加智能和自动化。
2.3.2 元配置
Section titled “2.3.2 元配置”interface DocActionMeta { type: "docAction" funcName: string docAction: { name: string description: string }}2.3.3 执行上下文
Section titled “2.3.3 执行上下文”文档动作函数接收两个参数:
input: 作为Record<string, any>的输入参数ctx: 包含docId和env的上下文对象
2.3.4 实现示例
Section titled “2.3.4 实现示例”export const meta = { type: "docAction", funcName: "calculateCompletion", docAction: { name: "计算完成度", description: "计算文档中待办事项的完成百分比", },}
export async function calculateCompletion( input: Record<string, any>, ctx: { docId: string }) { const { docId, env } = ctx const doc = await eidos.currentSpace.doc.getMarkdown(docId)
// 从 markdown 中提取 checkbox 的完成占比 const uncheckedCount = doc .split("\n") .filter((line) => line.startsWith("- [ ]")).length const checkedCount = doc .split("\n") .filter((line) => line.startsWith("- [x]")).length const totalCount = uncheckedCount + checkedCount const completion = totalCount > 0 ? (checkedCount / totalCount) * 100 : 0
await eidos.currentSpace.doc.setProperties(docId, { completion, })
return { completion, }}2.4 文件动作脚本
Section titled “2.4 文件动作脚本”2.4.1 概述
Section titled “2.4.1 概述”当 type 属性设置为 "fileAction" 时,脚本作为文件级动作,可以在特定文件上触发。这些动作通过文件右键菜单访问,实现后台文件处理功能,无需打开 UI 界面。
2.4.2 元配置
Section titled “2.4.2 元配置”interface FileActionMeta { type: "fileAction" funcName: string fileAction: { name: string description: string extensions: string[] // 支持的文件扩展名,如 [".jpg", ".png"] icon?: string // 可选图标 }}2.4.3 执行上下文
Section titled “2.4.3 执行上下文”文件动作函数接收两个参数:
filePath: 文件路径字符串(格式同 File Handler,支持~/和@/前缀)ctx: 上下文对象,包含env环境变量
2.4.4 实现示例
Section titled “2.4.4 实现示例”export const meta = { type: "fileAction", funcName: "compressImage", fileAction: { name: "压缩图片", description: "将图片压缩到原大小的 50%", extensions: [".jpg", ".jpeg", ".png"], icon: "🗜️" }}
export async function compressImage( filePath: string, ctx: { env: Record<string, string> }) { const { env } = ctx try { // 读取原始文件 const data = await eidos.currentSpace.fs.readFile(filePath)
// 压缩图片(使用第三方库,如 browser-image-compression) const compressed = await compressImageData(data, { maxSizeMB: 1, maxWidthOrHeight: 1920 })
// 生成新文件路径 const newPath = filePath.replace(/(\.\w+)$/, '_compressed$1') await eidos.currentSpace.fs.writeFile(newPath, compressed)
// 显示成功通知 eidos.currentSpace.notify({ title: "成功", description: `已压缩并保存到 ${newPath}` })
return { success: true, outputPath: newPath, originalSize: data.byteLength, compressedSize: compressed.byteLength } } catch (error) { eidos.currentSpace.notify({ title: "错误", description: `压缩失败: ${error.message}` }) return { success: false, error: error.message } }}2.4.5 用户体验流程
Section titled “2.4.5 用户体验流程”- 用户在文件树中右键点击文件
- 看到”文件动作”子菜单,列出所有支持该扩展名的
fileAction - 点击某个动作(如”压缩图片”)
- 脚本在后台执行
- 完成后显示通知,告知结果
2.4.6 文件访问 API
Section titled “2.4.6 文件访问 API”与 File Handler 相同,使用 eidos.currentSpace.fs API 访问文件:
// 读取文本文件const text = await eidos.currentSpace.fs.readFile(filePath, "utf8")
// 读取二进制文件const data = await eidos.currentSpace.fs.readFile(filePath)
// 写入文件await eidos.currentSpace.fs.writeFile(filePath, content, "utf8")
// 获取文件信息const stats = await eidos.currentSpace.fs.stat(filePath)更多文件系统 API 详情,请参阅 Space API 参考 - 文件系统 API。
2.5 用户自定义函数 (UDF) 脚本
Section titled “2.5 用户自定义函数 (UDF) 脚本”2.5.1 概述
Section titled “2.5.1 概述”当 type 属性设置为 "udf" 时,脚本创建可以在 SQL 查询中调用的数据库函数,扩展数据库的计算能力。
2.5.2 元配置
Section titled “2.5.2 元配置”interface UDFMeta { type: "udf" funcName: string udf: { name: string deterministic?: boolean }}2.5.3 UDF 类型
Section titled “2.5.3 UDF 类型”2.5.3.1 标量 UDF
Section titled “2.5.3.1 标量 UDF”标量 UDF 对单个值进行操作,每次调用返回单个结果。
export const meta = { type: "udf", funcName: "add", udf: { // add 是 SQL 中的保留字,所以我们使用不同的名称 name: "myAdd", deterministic: true, },}
function add(a: number, b: number) { return a + b}3. 安全注意事项
Section titled “3. 安全注意事项”脚本执行应该被适当沙箱化,以防止未经授权的系统访问。实现必须验证输入参数,并根据执行上下文强制执行适当的访问控制。
4. 实现要求
Section titled “4. 实现要求”- 所有脚本必须导出符合指定接口的
meta对象 meta.funcName属性中的函数名必须与实际导出的函数匹配- 应该为所有脚本类型实现输入验证
- 错误处理在所有执行上下文中必须保持一致
5. 未来扩展
Section titled “5. 未来扩展”本规范可能会扩展以支持其他脚本类型,例如:
- 事件处理器
- 数据验证器
- 自定义字段类型
- 工作流触发器