初始化创建自定义工具相关逻辑并实现页面更新的逻辑
修改文件路径:context\app-context.tsx
自定义工具自动管理功能
功能概述
自定义工具自动管理功能是一个在应用启动时自动检查、创建和更新自定义工具的系统。该功能确保系统中预定义的工具始终存在且保持最新状态,避免手动维护工具的繁琐过程。
执行时机和条件
执行时机
- 应用启动时自动执行
- 通过React的
useEffect钩子触发 - 依赖项:
isCurrentWorkspaceEditor和currentWorkspace?.id
执行条件
函数会在以下两个条件同时满足时执行:
-
用户权限检查:用户必须是工作区编辑者(
isCurrentWorkspaceEditor === true) -
工作区状态检查:工作区信息已加载完成(
currentWorkspace?.id存在)
如果任一条件不满足,函数会直接返回,不执行任何操作。
工具定义
预定义工具列表
系统维护一个预定义的工具列表toolsToCreate,包含需要自动管理的工具配置:
const toolsToCreate = [
{
name: "基础工具",
icon: { content: "📋", background: "#E3F2FD" },
schema: { /* OpenAPI 3.0.1 规范的 schema */ }
},
{
name: "数据执行工具",
icon: { content: "🗄️", background: "#FFF3E0" },
schema: { /* OpenAPI 3.0.1 规范的 schema */ }
}
// 可以添加更多工具...
]
工具配置结构
每个工具配置包含:
-
name: 工具唯一标识符 -
icon: 工具显示图标(包含内容和背景色) -
schema: OpenAPI 3.0.1 规范的工具定义
检查逻辑
获取现有工具
系统首先调用API获取当前工作区所有已存在的工具集合:
const collections = await fetchCollectionList()
工具存在性判断
对于每个预定义工具,系统检查是否已存在:
const toolExists = collections.some(collection =>
collection.type === 'api' && collection.name === tool.name
)
判断标准:
- 工具类型必须为
'api'(自定义工具) - 工具名称必须与预定义工具名称完全匹配
创建和更新逻辑
工具数据结构
无论是创建还是更新,都使用统一的数据结构:
const toolData = {
provider: tool.name, // 工具名称
credentials: {
auth_type: AuthType.apiKeyHeader, // 认证类型
api_key_header: "Authorization", // API Key header 名称
api_key_value: "8s9K7m8P0z5LI9o0P8l7K9j8H7g", // API Key 值
api_key_header_prefix: AuthHeaderPrefix.bearer // header 前缀
},
icon: tool.icon, // 工具图标
schema_type: "openapi", // 模式类型
schema: JSON.stringify(tool.schema), // OpenAPI 模式(JSON字符串)
privacy_policy: "", // 隐私政策
custom_disclaimer: "", // 自定义免责声明
id: tool.name, // 工具 ID
labels: [] // 工具标签
}
创建逻辑
当工具不存在时(toolExists === false),调用创建接口:
if (!toolExists) {
await createCustomCollection(toolData)
}
创建接口详情:
-
端点:
POST /workspaces/current/tool-provider/api/add - 参数:完整的工具数据对象
-
特点:静默执行(
silent: true),不显示加载状态
更新逻辑
当工具已存在时(toolExists === true),调用更新接口:
else {
await updateCustomCollection({
...toolData,
original_provider: tool.name // 原始工具名称(必需字段)
})
}
更新接口详情:
-
端点:
POST /workspaces/current/tool-provider/api/update -
参数:工具数据对象 +
original_provider字段 -
关键字段:
original_provider是更新操作的必需字段,用于标识要更新的原始工具
并行执行
系统使用Promise.all()并行执行所有工具的创建或更新操作:
const creationPromises = toolsToCreate.map(async (tool) => {
// 工具检查和处理逻辑
})
await Promise.all(creationPromises)
优势:
- 提高执行效率
- 减少总体等待时间
- 单个工具失败不影响其他工具
错误处理
单个工具级别错误处理
每个工具的操作都有独立的错误捕获:
try {
// 创建或更新操作
} catch (error) {
console.error(`Error ${toolExists ? 'updating' : 'creating'} tool ${tool.name}:`, error)
}
处理策略:
- 记录详细的错误信息
- 区分创建和更新操作的错误信息
- 单个工具失败不影响其他工具的执行
全局错误处理
整个流程也有错误捕获:
try {
// 获取工具列表和执行创建/更新操作
} catch (error) {
console.error('Error checking or creating custom tools:', error)
}
处理策略:
- 记录全局错误
- 不影响应用正常运行
- 确保应用其他功能不受影响
API接口说明
1. 获取工具列表
fetchCollectionList()
-
端点:
GET /workspaces/current/tool-providers - 返回:当前工作区所有工具集合列表
2. 创建自定义工具
createCustomCollection(collection)
-
端点:
POST /workspaces/current/tool-provider/api/add - 参数:完整的工具配置对象
- 特性:静默执行
3. 更新自定义工具
updateCustomCollection(collection)
-
端点:
POST /workspaces/current/tool-provider/api/update -
参数:工具配置对象 +
original_provider字段 -
注意:
original_provider为必需字段
数据类型定义
CustomCollectionBackend
interface CustomCollectionBackend {
provider: string // 工具名称
credentials: Credential // 认证信息
icon: { content: string, background: string } // 图标
schema_type: string // 模式类型("openapi")
schema: string // OpenAPI schema(JSON字符串)
privacy_policy: string // 隐私政策
custom_disclaimer: string // 免责声明
id: string // 工具 ID
labels: string[] // 标签
original_provider?: string // 原始工具名称(更新时必需)
}
Credential
interface Credential {
auth_type: string // 认证类型
api_key_header: string // API Key header 名称
api_key_value: string // API Key 值
api_key_header_prefix: string // header 前缀
}
注意事项
1. 权限要求
- 用户必须具有工作区编辑权限
- 没有权限时不会执行任何操作
2. 工具名称匹配
- 工具名称必须完全匹配
- 区分大小写
3. 更新操作
- 更新时必须包含
original_provider字段 - 该字段值应与
provider字段相同
4. 错误处理
- 单个工具失败不影响其他工具
- 全局错误不会影响应用运行
5. 性能考虑
- 使用并行执行提高效率
- 避免阻塞应用启动
扩展性
添加新工具
在toolsToCreate数组中添加新的工具配置:
const toolsToCreate = [
// 现有工具...
{
name: "新工具名称",
icon: { content: "🔧", background: "#E8F5E9" },
schema: { /* OpenAPI schema */ }
}
]
修改现有工具
直接修改对应工具的配置,系统会自动检测并更新已存在的工具。
自定义认证方式
修改credentials配置以支持不同的认证方式:
credentials: {
auth_type: AuthType.customType, // 自定义认证类型
// 其他认证参数
}
总结
自定义工具自动管理功能通过智能的检查、创建和更新机制,确保系统中预定义的工具始终保持最新状态。该功能具有以下特点:
- 自动化:无需手动干预,自动执行
- 智能化:根据工具存在状态选择合适的操作
- 健壮性:完善的错误处理机制
- 高效性:并行执行,提高性能
- 可扩展:易于添加新工具和修改现有配置
代码
useEffect(() => {
/**
* 检查并创建自定义工具
* 功能:当用户进入首页时,如果不存在指定的自定义工具,则自动创建它们
*/
const checkAndCreateCustomTools = async () => {
// 跳过条件:
// 1. 用户不是工作区编辑者(没有创建工具的权限)
// 2. 工作区信息未加载完成
// - 第一个条件 : !isCurrentWorkspaceEditor
// - isCurrentWorkspaceEditor 是一个布尔值,表示用户是否具有工作区编辑权限
// - !isCurrentWorkspaceEditor 表示用户不是工作区编辑者,即没有创建工具的权限
// - 第二个条件 : !currentWorkspace?.id
// - currentWorkspace 是当前工作区的信息对象
// - ?. 是可选链操作符,用于安全访问对象属性
// - currentWorkspace?.id 表示获取工作区的 ID,如果 currentWorkspace 为 null 或 undefined,则返回 undefined
// - !currentWorkspace?.id 表示工作区没有 ID,即工作区信息未加载完成
if (!isCurrentWorkspaceEditor || !currentWorkspace?.id) {
return
}
// 定义要创建的工具列表
const toolsToCreate = [
......//省略
]
try {
// 获取现有的工具集合列表 调用接口查询所有工具集合
const collections = await fetchCollectionList()
// 准备需要创建或更新的工具的 Promise 列表
const creationPromises = toolsToCreate.map(async (tool) => {
// 检查是否已存在该工具
// 只检查类型为 'api' 的工具(自定义工具)
const toolExists = collections.some(collection =>
collection.type === 'api' && collection.name === tool.name
)
try {
const toolData = {
provider: tool.name, // 工具名称
credentials: {
auth_type: AuthType.apiKeyHeader, // 认证类型:API Key Header
api_key_header: "Authorization", // API Key header 名称
api_key_value: "8s9K7m8P0z5L9q8I9o0P8l7K9j8H7g", // API Key 值
api_key_header_prefix: AuthHeaderPrefix.bearer // API Key header 前缀
},
icon: tool.icon, // 工具图标
schema_type: "openapi", // 模式类型:OpenAPI
schema: JSON.stringify(tool.schema), // OpenAPI 模式
privacy_policy: "", // 隐私政策(空字符串)
custom_disclaimer: "", // 自定义免责声明(空字符串)
id: tool.name, // 工具 ID
labels: [] // 工具标签(空数组)
}
// 根据工具是否存在,决定调用创建接口还是更新接口
if (!toolExists) {
// 创建自定义工具
await createCustomCollection(toolData)
} else {
// 更新自定义工具,需要添加 original_provider 字段
await updateCustomCollection({
...toolData,
original_provider: tool.name // 原始工具名称
})
}
// 在 localStorage 中标记该工具已创建,避免重复创建
// localStorage.setItem(localStorageKey, 'true')
} catch (error) {
// 单个工具操作失败不影响其他工具
console.error(`Error ${toolExists ? 'updating' : 'creating'} tool ${tool.name}:`, error)
}
})
// 并行执行所有工具创建或更新操作
await Promise.all(creationPromises)
} catch (error) {
// 错误处理:记录错误但不影响应用正常运行
console.error('Error checking or creating custom tools:', error)
}
}
// 执行检查和创建操作
checkAndCreateCustomTools()
}, [isCurrentWorkspaceEditor, currentWorkspace?.id]) // 依赖项:编辑权限和工作区 ID