UNPKG

@cherrystudio/ai-core

Version:

Cherry Studio AI Core - Unified AI Provider Interface Based on Vercel AI SDK

195 lines (192 loc) 4.81 kB
//#region src/core/plugins/manager.ts /** * 插件管理器 */ var PluginManager = class { plugins = []; constructor(plugins = []) { this.plugins = this.sortPlugins(plugins); } /** * 添加插件 */ use(plugin) { this.plugins = this.sortPlugins([...this.plugins, plugin]); return this; } /** * 移除插件 */ remove(pluginName) { this.plugins = this.plugins.filter((p) => p.name !== pluginName); return this; } /** * 插件排序:pre -> normal -> post */ sortPlugins(plugins) { const pre = []; const normal = []; const post = []; plugins.forEach((plugin) => { if (plugin.enforce === "pre") pre.push(plugin); else if (plugin.enforce === "post") post.push(plugin); else normal.push(plugin); }); return [ ...pre, ...normal, ...post ]; } /** * 执行 First 钩子 - 返回第一个有效结果 */ async executeFirst(hookName, arg, context) { for (const plugin of this.plugins) { const hook = plugin[hookName]; if (hook) { const result = await hook(arg, context); if (result !== null && result !== void 0) return result; } } return null; } /** * 执行 Sequential 钩子 - 链式数据转换 */ async executeSequential(hookName, initialValue, context) { let result = initialValue; for (const plugin of this.plugins) { const hook = plugin[hookName]; if (hook) result = await hook(result, context); } return result; } /** * 执行 ConfigureContext 钩子 - 串行配置上下文 */ async executeConfigureContext(context) { for (const plugin of this.plugins) { const hook = plugin.configureContext; if (hook) await hook(context); } } /** * 执行 Parallel 钩子 - 并行副作用 */ async executeParallel(hookName, context, result, error) { const promises = this.plugins.map((plugin) => { const hook = plugin[hookName]; if (!hook) return null; if (hookName === "onError" && error) return hook(error, context); else if (hookName === "onRequestEnd" && result !== void 0) return hook(context, result); else if (hookName === "onRequestStart") return hook(context); return null; }).filter(Boolean); await Promise.all(promises); } /** * 收集所有流转换器(返回数组,AI SDK 原生支持) */ collectStreamTransforms(params, context) { return this.plugins.filter((plugin) => plugin.transformStream).map((plugin) => plugin.transformStream?.(params, context)); } /** * 获取所有插件信息 */ getPlugins() { return [...this.plugins]; } /** * 获取插件统计信息 */ getStats() { const stats = { total: this.plugins.length, pre: 0, normal: 0, post: 0, hooks: { resolveModel: 0, loadTemplate: 0, transformParams: 0, transformResult: 0, onRequestStart: 0, onRequestEnd: 0, onError: 0, transformStream: 0 } }; this.plugins.forEach((plugin) => { if (plugin.enforce === "pre") stats.pre++; else if (plugin.enforce === "post") stats.post++; else stats.normal++; Object.keys(stats.hooks).forEach((hookName) => { if (plugin[hookName]) stats.hooks[hookName]++; }); }); return stats; } }; //#endregion //#region src/core/plugins/index.ts function createContext(providerId, modelId, originalParams) { return { providerId, modelId, originalParams, metadata: {}, startTime: Date.now(), requestId: `${providerId}-${modelId}-${Date.now()}-${Math.random().toString(36).slice(2)}`, recursiveCall: () => Promise.resolve(null) }; } function definePlugin(plugin) { return plugin; } //#endregion //#region src/core/options/factory.ts /** * 创建特定供应商的选项 * @param provider 供应商名称 * @param options 供应商特定的选项 * @returns 格式化的provider options */ function createProviderOptions(provider, options) { return { [provider]: options }; } /** * 合并多个供应商的options * @param optionsMap 包含多个供应商选项的对象 * @returns 合并后的TypedProviderOptions */ function mergeProviderOptions(...optionsMap) { return Object.assign({}, ...optionsMap); } /** * 创建OpenAI供应商选项的便捷函数 */ function createOpenAIOptions(options) { return createProviderOptions("openai", options); } /** * 创建Anthropic供应商选项的便捷函数 */ function createAnthropicOptions(options) { return createProviderOptions("anthropic", options); } /** * 创建Google供应商选项的便捷函数 */ function createGoogleOptions(options) { return createProviderOptions("google", options); } /** * 创建XAI供应商选项的便捷函数 */ function createXaiOptions(options) { return createProviderOptions("xai", options); } //#endregion export { PluginManager, createAnthropicOptions, createContext, createGoogleOptions, createOpenAIOptions, createXaiOptions, definePlugin, mergeProviderOptions };