UNPKG

@cherrystudio/ai-core

Version:

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

548 lines (541 loc) 18.9 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_plugins = require('./plugins-Dxz_fOwT.cjs'); const require_initialization = require('./initialization-CThbOFZ0.cjs'); let ai = require("ai"); //#region src/core/models/utils.ts const isV2Model = (model) => { return typeof model === "object" && model !== null && model.specificationVersion === "v2"; }; const isV3Model = (model) => { return typeof model === "object" && model !== null && model.specificationVersion === "v3"; }; //#endregion //#region src/core/runtime/errors.ts /** * Error classes for runtime operations */ /** * Error thrown when image generation fails */ var ImageGenerationError = class ImageGenerationError extends Error { constructor(message, providerId, modelId, cause) { super(message); this.providerId = providerId; this.modelId = modelId; this.cause = cause; this.name = "ImageGenerationError"; if (Error.captureStackTrace) Error.captureStackTrace(this, ImageGenerationError); } }; /** * Error thrown when model resolution fails during image generation */ var ImageModelResolutionError = class extends ImageGenerationError { constructor(modelId, providerId, cause) { super(`Failed to resolve image model: ${modelId}${providerId ? ` for provider: ${providerId}` : ""}`, providerId, modelId, cause); this.name = "ImageModelResolutionError"; } }; //#endregion //#region src/core/errors/index.ts /** * AI Core Error System * Unified error handling for the AI Core package */ /** * Base error class for all AI Core errors * Provides structured error information with error codes, context, and cause tracking */ var AiCoreError = class extends Error { constructor(code, message, context, cause) { super(message); this.code = code; this.context = context; this.cause = cause; this.name = "AiCoreError"; if (cause) this.stack = `${this.stack}\nCaused by: ${cause.stack}`; } toJSON() { return { name: this.name, code: this.code, message: this.message, context: this.context, cause: this.cause ? { name: this.cause.name, message: this.cause.message } : void 0 }; } }; /** * Recursive depth limit exceeded error * Thrown when recursive calls exceed the maximum allowed depth */ var RecursiveDepthError = class extends AiCoreError { constructor(requestId, currentDepth, maxDepth) { super("RECURSIVE_DEPTH_EXCEEDED", `Maximum recursive depth (${maxDepth}) exceeded at depth ${currentDepth}`, { requestId, currentDepth, maxDepth }); this.name = "RecursiveDepthError"; } }; /** * Model resolution failure error * Thrown when a model ID cannot be resolved to a model instance */ var ModelResolutionError = class extends AiCoreError { constructor(modelId, providerId, cause) { super("MODEL_RESOLUTION_FAILED", `Failed to resolve model: ${modelId}`, { modelId, providerId }, cause); this.name = "ModelResolutionError"; } }; /** * Parameter validation error * Thrown when request parameters fail validation */ var ParameterValidationError = class extends AiCoreError { constructor(paramName, reason, value) { super("PARAMETER_VALIDATION_FAILED", `Invalid parameter '${paramName}': ${reason}`, { paramName, reason, value }); this.name = "ParameterValidationError"; } }; /** * Plugin execution error * Thrown when a plugin fails during execution */ var PluginExecutionError = class extends AiCoreError { constructor(pluginName, hookName, cause) { super("PLUGIN_EXECUTION_FAILED", `Plugin '${pluginName}' failed in hook '${hookName}'`, { pluginName, hookName }, cause); this.name = "PluginExecutionError"; } }; /** * Template loading error * Thrown when a template cannot be loaded */ var TemplateLoadError = class extends AiCoreError { constructor(templateName, cause) { super("TEMPLATE_LOAD_FAILED", `Failed to load template: ${templateName}`, { templateName }, cause); this.name = "TemplateLoadError"; } }; //#endregion //#region src/core/runtime/pluginEngine.ts /** * 插件增强的 AI 客户端 * 专注于插件处理,不暴露用户API */ var PluginEngine = class { constructor(providerId, plugins = []) { this.providerId = providerId; this.basePlugins = []; this.basePlugins = plugins; } /** * 添加插件 */ use(plugin) { this.basePlugins.push(plugin); return this; } /** * 批量添加插件 */ usePlugins(plugins) { this.basePlugins.push(...plugins); return this; } /** * 移除插件 */ removePlugin(pluginName) { this.basePlugins = this.basePlugins.filter((p) => p.name !== pluginName); return this; } /** * 获取插件统计 */ getPluginStats() { return new require_plugins.PluginManager(this.basePlugins).getStats(); } /** * 获取所有插件 */ getPlugins() { return [...this.basePlugins]; } /** * 执行带插件的操作(非流式) * 提供给AiExecutor使用 */ async executeWithPlugins(methodName, params, executor, _context) { let resolvedModel; let modelId; const { model } = params; if (typeof model === "string") modelId = model; else { resolvedModel = model; modelId = model.modelId; } const context = _context ?? require_plugins.createContext(this.providerId, model, params); const manager = new require_plugins.PluginManager(this.basePlugins); context.recursiveCall = async (newParams) => { if (context.recursiveDepth >= context.maxRecursiveDepth) throw new RecursiveDepthError(context.requestId, context.recursiveDepth, context.maxRecursiveDepth); const previousDepth = context.recursiveDepth; const wasRecursive = context.isRecursiveCall; try { context.recursiveDepth = previousDepth + 1; context.isRecursiveCall = true; return await this.executeWithPlugins(methodName, { ...params, ...newParams }, executor, context); } finally { context.recursiveDepth = previousDepth; context.isRecursiveCall = wasRecursive; } }; try { await manager.executeConfigureContext(context); await manager.executeParallel("onRequestStart", context); if (typeof model === "string") { const resolved = await manager.executeFirst("resolveModel", modelId, context); if (!resolved) throw new ModelResolutionError(modelId, this.providerId); resolvedModel = resolved; } if (!resolvedModel) throw new ModelResolutionError(modelId, this.providerId); if (context.middlewares && context.middlewares.length > 0) resolvedModel = (0, ai.wrapLanguageModel)({ model: resolvedModel, middleware: context.middlewares }); const transformedParams = await manager.executeTransformParams(params, context); const result = await executor(resolvedModel, transformedParams); const transformedResult = await manager.executeTransformResult(result, context); await manager.executeParallel("onRequestEnd", context, transformedResult); return transformedResult; } catch (error) { await manager.executeParallel("onError", context, void 0, error); throw error; } } /** * 执行带插件的图像生成操作 * 提供给AiExecutor使用 */ async executeImageWithPlugins(methodName, params, executor, _context) { let resolvedModel; let modelId; const { model } = params; if (typeof model === "string") modelId = model; else { resolvedModel = model; modelId = model.modelId; } const context = _context ?? require_plugins.createContext(this.providerId, model, params); const manager = new require_plugins.PluginManager(this.basePlugins); context.recursiveCall = async (newParams) => { if (context.recursiveDepth >= context.maxRecursiveDepth) throw new RecursiveDepthError(context.requestId, context.recursiveDepth, context.maxRecursiveDepth); const previousDepth = context.recursiveDepth; const wasRecursive = context.isRecursiveCall; try { context.recursiveDepth = previousDepth + 1; context.isRecursiveCall = true; return await this.executeImageWithPlugins(methodName, { ...params, ...newParams }, executor, context); } finally { context.recursiveDepth = previousDepth; context.isRecursiveCall = wasRecursive; } }; try { await manager.executeConfigureContext(context); await manager.executeParallel("onRequestStart", context); if (typeof model === "string") { const resolved = await manager.executeFirst("resolveModel", modelId, context); if (!resolved) throw new ModelResolutionError(modelId, this.providerId); resolvedModel = resolved; } if (!resolvedModel) throw new ModelResolutionError(modelId, this.providerId); const transformedParams = await manager.executeTransformParams(params, context); const result = await executor(resolvedModel, transformedParams); const transformedResult = await manager.executeTransformResult(result, context); await manager.executeParallel("onRequestEnd", context, transformedResult); return transformedResult; } catch (error) { await manager.executeParallel("onError", context, void 0, error); throw error; } } /** * 执行流式调用的通用逻辑(支持流转换器) * 提供给AiExecutor使用 */ async executeStreamWithPlugins(methodName, params, executor, _context) { let resolvedModel; let modelId; const { model } = params; if (typeof model === "string") modelId = model; else { resolvedModel = model; modelId = model.modelId; } const context = _context ?? require_plugins.createContext(this.providerId, model, params); const manager = new require_plugins.PluginManager(this.basePlugins); context.recursiveCall = async (newParams) => { if (context.recursiveDepth >= context.maxRecursiveDepth) throw new RecursiveDepthError(context.requestId, context.recursiveDepth, context.maxRecursiveDepth); const previousDepth = context.recursiveDepth; const wasRecursive = context.isRecursiveCall; try { context.recursiveDepth = previousDepth + 1; context.isRecursiveCall = true; return await this.executeStreamWithPlugins(methodName, { ...params, ...newParams }, executor, context); } finally { context.recursiveDepth = previousDepth; context.isRecursiveCall = wasRecursive; } }; try { await manager.executeConfigureContext(context); await manager.executeParallel("onRequestStart", context); if (typeof model === "string") { const resolved = await manager.executeFirst("resolveModel", modelId, context); if (!resolved) throw new ModelResolutionError(modelId, this.providerId); resolvedModel = resolved; context.model = resolvedModel; } if (!resolvedModel) throw new ModelResolutionError(modelId, this.providerId); if (context.middlewares && context.middlewares.length > 0) { if (typeof resolvedModel === "string") throw new Error(`Model must be resolved before applying middlewares, got string: ${resolvedModel}`); resolvedModel = (0, ai.wrapLanguageModel)({ model: resolvedModel, middleware: context.middlewares }); } const transformedParams = await manager.executeTransformParams(params, context); const streamTransforms = manager.collectStreamTransforms(transformedParams, context); const result = executor(resolvedModel, transformedParams, streamTransforms); const transformedResult = await manager.executeTransformResult(result, context); await manager.executeParallel("onRequestEnd", context, transformedResult); return transformedResult; } catch (error) { await manager.executeParallel("onError", context, void 0, error); throw error; } } }; //#endregion //#region src/core/runtime/executor.ts var RuntimeExecutor = class RuntimeExecutor { constructor(config) { this.config = config; this.pluginEngine = new PluginEngine(config.providerId, config.plugins || []); const provider = config.provider; if (!provider.embeddingModel && provider.textEmbeddingModel) provider.embeddingModel = (modelId) => provider.textEmbeddingModel(modelId); this.registry = (0, ai.createProviderRegistry)({ [config.providerId]: provider }); } createResolveModelPlugin() { return require_plugins.definePlugin({ name: "_internal_resolveModel", enforce: "post", resolveModel: async (modelId) => { return await this.resolveModel(modelId); } }); } createResolveImageModelPlugin() { return require_plugins.definePlugin({ name: "_internal_resolveImageModel", enforce: "post", resolveModel: async (modelId) => { return await this.resolveImageModel(modelId); } }); } createConfigureContextPlugin() { return require_plugins.definePlugin({ name: "_internal_configureContext", configureContext: async () => {} }); } /** * 流式文本生成 */ async streamText(params) { const { model } = params; if (typeof model === "string") this.pluginEngine.usePlugins([this.createResolveModelPlugin(), this.createConfigureContextPlugin()]); else this.pluginEngine.usePlugins([this.createConfigureContextPlugin()]); return this.pluginEngine.executeStreamWithPlugins("streamText", params, (resolvedModel, transformedParams, streamTransforms) => { const experimental_transform = params?.experimental_transform ?? (streamTransforms.length > 0 ? streamTransforms : void 0); return (0, ai.streamText)({ ...transformedParams, model: resolvedModel, experimental_transform }); }); } /** * 生成文本 */ async generateText(params) { const { model } = params; if (typeof model === "string") this.pluginEngine.usePlugins([this.createResolveModelPlugin(), this.createConfigureContextPlugin()]); else this.pluginEngine.usePlugins([this.createConfigureContextPlugin()]); return this.pluginEngine.executeWithPlugins("generateText", params, (resolvedModel, transformedParams) => (0, ai.generateText)({ ...transformedParams, model: resolvedModel })); } /** * 生成图像 */ async generateImage(params) { try { const { model } = params; if (typeof model === "string") this.pluginEngine.usePlugins([this.createResolveImageModelPlugin(), this.createConfigureContextPlugin()]); else this.pluginEngine.usePlugins([this.createConfigureContextPlugin()]); return this.pluginEngine.executeImageWithPlugins("generateImage", params, (resolvedModel, transformedParams) => (0, ai.generateImage)({ ...transformedParams, model: resolvedModel })); } catch (error) { if (error instanceof Error) { const modelId = typeof params.model === "string" ? params.model : params.model.modelId; throw new ImageGenerationError(`Failed to generate image: ${error.message}`, this.config.providerId, modelId, error); } throw error; } } /** * 批量嵌入文本 */ async embedMany(params) { const { model: modelOrId, ...options } = params; return (0, ai.embedMany)({ model: typeof modelOrId === "string" ? this.registry.embeddingModel(`${this.config.providerId}:${modelOrId}`) : modelOrId, ...options }); } /** * 解析模型:将字符串 modelId 解析为 model 对象 * * 对于有 modelResolver 的配置(如 xAI responses, OpenAI chat), * 使用 resolver 函数解析模型,而不是通过 registry.languageModel()。 * resolver 在 extension 声明处类型安全地捕获了具体 provider 方法。 */ async resolveModel(modelOrId) { if (typeof modelOrId === "string") { if (this.config.modelResolver) return this.config.modelResolver(modelOrId); return this.registry.languageModel(`${this.config.providerId}:${modelOrId}`); } else { if (!isV3Model(modelOrId)) throw new Error(`Model must be V3. Provider "${this.config.providerId}" returned a V2 model. All providers should be wrapped with wrapProvider to return V3 models.`); return modelOrId; } } /** * 解析图像模型:如果是字符串则创建图像模型,如果是模型则直接返回 */ async resolveImageModel(modelOrId) { try { if (typeof modelOrId === "string") return this.registry.imageModel(`${this.config.providerId}:${modelOrId}`); else return modelOrId; } catch (error) { throw new ImageModelResolutionError(typeof modelOrId === "string" ? modelOrId : modelOrId.modelId, this.config.providerId, error instanceof Error ? error : void 0); } } /** * 创建执行器 - 支持已知provider的类型安全 */ static create(providerId, provider, options, plugins, modelResolver) { return new RuntimeExecutor({ providerId, provider, providerSettings: options, plugins, modelResolver }); } /** * 创建OpenAI Compatible执行器 * ✅ Now accepts provider instance directly */ static createOpenAICompatible(provider, options, plugins = []) { return new RuntimeExecutor({ providerId: "openai-compatible", provider, providerSettings: options, plugins }); } }; //#endregion //#region src/core/runtime/index.ts /** * 创建运行时执行器 - 支持类型安全的已知provider * 自动确保 provider 已初始化 */ async function createExecutor(providerId, options, plugins) { if (!require_initialization.extensionRegistry.has(providerId)) throw new Error(`Provider extension "${providerId}" not registered`); const provider = await require_initialization.extensionRegistry.createProvider(providerId, options || {}); const resolver = require_initialization.extensionRegistry.getModelResolver(providerId); const modelResolver = resolver ? (modelId) => resolver(provider, modelId) : void 0; return RuntimeExecutor.create(providerId, provider, options, plugins, modelResolver); } /** * 直接流式文本生成 */ async function streamText(providerId, options, params, plugins) { return (await createExecutor(providerId, options, plugins)).streamText(params); } /** * 直接生成文本 */ async function generateText(providerId, options, params, plugins) { return (await createExecutor(providerId, options, plugins)).generateText(params); } /** * 直接生成图像 - 支持middlewares */ async function generateImage(providerId, options, params, plugins) { return (await createExecutor(providerId, options, plugins)).generateImage(params); } /** * 直接批量嵌入文本 * AI SDK v6 只有 embedMany,没有 embed */ async function embedMany(providerId, options, params, plugins) { return (await createExecutor(providerId, options, plugins)).embedMany(params); } //#endregion exports.AiCoreError = AiCoreError; exports.ModelResolutionError = ModelResolutionError; exports.ParameterValidationError = ParameterValidationError; exports.PluginEngine = PluginEngine; exports.PluginExecutionError = PluginExecutionError; exports.RecursiveDepthError = RecursiveDepthError; exports.TemplateLoadError = TemplateLoadError; exports.createExecutor = createExecutor; exports.definePlugin = require_plugins.definePlugin; exports.embedMany = embedMany; exports.generateImage = generateImage; exports.generateText = generateText; exports.isV2Model = isV2Model; exports.isV3Model = isV3Model; exports.streamText = streamText;