@cherrystudio/ai-core
Version:
Cherry Studio AI Core - Unified AI Provider Interface Based on Vercel AI SDK
195 lines (192 loc) • 4.81 kB
JavaScript
//#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 };