import { Logger, OnModuleInit, OnModuleDestroy, DynamicModule } from '@nestjs/common'; import { PlatformHttpClient, RequestContextService, HttpClientFactory } from '@lark-apaas/nestjs-common'; import { ZodSchema } from 'zod'; import { Response } from 'express'; /** * 事件类型 */ type EventType = 'install' | 'create_instance' | 'call'; /** * 调用者类型 */ type CallerType = 'client' | 'server' | 'debug'; /** * 资源事件 */ interface ResourceEvent { resourceType: 'plugin'; resourceKey: string; eventType: EventType; details?: Record; } /** * Call 事件详情 */ interface CallEventDetails { version: string; success: string; duration: string; is_stream: string; caller_type: string; status_code: string; } /** * 插件遥测服务 * * 负责上报插件生命周期事件到平台 */ declare class TelemetryService { private readonly client; private readonly logger; constructor(client: PlatformHttpClient); /** * 上报事件到平台 * * @param events - 事件列表 * @returns 是否上报成功 */ reportEvents(events: ResourceEvent[]): Promise; /** * 上报插件调用事件 * * @param pluginKey - 插件标识 * @param details - 调用详情 */ reportCall(pluginKey: string, details: CallEventDetails): Promise; } interface UserContext { userId: string; tenantId: string; appId: string; /** 是否为系统账号 */ isSystemAccount: boolean; } interface PluginActionContext { /** 插件标识(如 @official/ai-chat) */ pluginKey: string; logger: Logger; platformHttpClient: PlatformHttpClient; userContext: UserContext; /** 是否为调试模式(来自 debug controller 的调用) */ isDebug: boolean; /** 调用来源:client=前端SDK, server=服务端内部, debug=调试面板 */ caller?: CallerType; } interface JSONSchema { type?: string; properties?: Record; required?: string[]; items?: JSONSchema; [key: string]: unknown; } interface CapabilityConfig { id: string; pluginKey: string; pluginVersion: string; name: string; description: string; paramsSchema: JSONSchema; formValue: Record; createdAt: number; updatedAt: number; } /** * 成功响应基础结构 */ interface SuccessResponse { status_code: '0'; data: T; } /** * 错误响应结构 */ interface ErrorResponse { status_code: string; error_msg: string; /** 是否为计费受限错误(当 status_code 为业务错误码时为 true) */ is_rate_limit_error?: boolean; } /** * Debug 信息 */ interface DebugInfo { capabilityConfig: CapabilityConfig; resolvedParams: unknown; duration: number; pluginID: string; action: string; } /** * 执行接口响应 data 结构 */ interface ExecuteResponseData { output: unknown; } /** * Debug 执行接口响应 data 结构 */ interface DebugExecuteResponseData { output: unknown; debug: DebugInfo; } /** * 能力列表项 */ interface CapabilityListItem { id: string; name: string; pluginID: string; pluginVersion: string; } /** * 列表接口响应 data 结构 */ interface ListResponseData { capabilities: CapabilityListItem[]; } /** * 流式内容响应 */ interface StreamContentResponse { status_code: '0'; data: { type: 'content'; delta: unknown; finished?: boolean; }; } /** * 流式错误响应 */ interface StreamErrorResponse { status_code: '0'; data: { type: 'error'; error: { /** 错误码,计费受限时为业务错误码(如 k_st_ec_400002687),其他情况为框架错误码 */ code: string; message: string; /** 是否为计费受限错误 */ isRateLimitError?: boolean; }; }; } /** * 流式响应类型 */ type StreamResponse = StreamContentResponse | StreamErrorResponse; /** * 流完成元数据 */ interface StreamDoneMetadata { /** chunk 总数 */ chunks: number; /** 流持续时间 (ms) */ duration: number; /** 聚合结果(可选) */ aggregated?: unknown; } /** * 流错误信息 */ interface StreamError { code: string; message: string; details?: unknown; /** 计费受限时的业务错误码(仅 code 为 RATE_LIMIT_EXCEEDED 时存在) */ rateLimitCode?: string; /** 计费受限时的业务错误消息(仅 code 为 RATE_LIMIT_EXCEEDED 时存在) */ rateLimitMessage?: string; } /** * 流事件类型 * - data: 数据事件,包含单个 chunk * - done: 完成事件,包含元数据 * - error: 错误事件,包含错误信息 */ type StreamEvent = { type: 'data'; data: T; } | { type: 'done'; metadata: StreamDoneMetadata; } | { type: 'error'; error: StreamError; }; interface ActionSchema { input: ZodSchema | ((config: unknown) => ZodSchema); output?: ZodSchema | ((input: unknown, config: unknown) => ZodSchema); } interface PluginInstance { /** 执行指定 action(unary) */ run(actionName: string, context: PluginActionContext, input: unknown): Promise; /** 检查 action 是否存在 */ hasAction(actionName: string): boolean; /** 获取 action 的 schema */ getActionSchema(actionName: string): ActionSchema | null; /** 获取解析后的 input schema */ getInputSchema(actionName: string, config?: unknown): ZodSchema | undefined; /** 获取解析后的 output schema */ getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined; /** 列出所有 action */ listActions(): string[]; /** 流式执行指定 action,返回原始流 */ runStream?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable; /** 流式执行指定 action,返回带事件协议的流(推荐) */ runStreamWithEvents?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable>; /** 检查 action 是否为流式 */ isStreamAction?(actionName: string): boolean; /** 聚合流式结果(可选,插件自定义聚合逻辑) */ aggregate?(actionName: string, chunks: unknown[]): unknown; } interface PluginPackage { create(config?: unknown): PluginInstance; } /** * Capability 模块错误码 */ declare const ErrorCodes: { /** 成功 */ readonly SUCCESS: "0"; /** 能力不存在 */ readonly CAPABILITY_NOT_FOUND: "k_ec_cap_001"; /** 插件不存在 */ readonly PLUGIN_NOT_FOUND: "k_ec_cap_002"; /** Action 不存在 */ readonly ACTION_NOT_FOUND: "k_ec_cap_003"; /** 参数验证失败 */ readonly PARAMS_VALIDATION_ERROR: "k_ec_cap_004"; /** 执行失败 */ readonly EXECUTION_ERROR: "k_ec_cap_005"; /** 计费受限 */ readonly RATE_LIMIT_EXCEEDED: "k_ec_cap_006"; }; type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes]; /** * 模板引擎服务 * * 支持语法: * - expr: '{{' + selector + '}}' * - selector: 'input.' + ident | selector.ident * - ident: [a-zA-Z_]([a-zA-Z_0-9])* * * 示例: * - {{input.a}} * - {{input.a.b}} * - "this is {{input.a.b}}" * * 求值规则: * - 如果整个字符串是单个表达式,保留原始类型 * - 如果是字符串插值(多个表达式或混合内容),返回字符串 * - 如果变量不存在: * - 未传 schema:返回原始表达式 * - 传了 schema(整串表达式):按 schema 返回默认值 * - 传了 schema(字符串插值):保留原始表达式 */ declare class TemplateEngineService { private readonly EXPR_REGEX; private readonly WHOLE_STRING_EXPR_REGEX; /** * 解析 formValue 模板 * @param template - formValue 模板对象 * @param input - 用户输入参数 * @param paramsSchema - 可选,输入参数的 JSON Schema,用于推断默认值 * @returns 解析后的参数对象 */ resolve(template: unknown, input: Record, paramsSchema?: JSONSchema): unknown; private resolveString; private resolveObject; private getValueByPath; /** * 根据路径从 schema 获取默认值 * @param path - 变量路径,如 "a.b.c" * @param schema - JSON Schema * @returns 默认值,如果无法确定则返回 undefined */ private getDefaultValueForPath; /** * 根据路径查找对应的 schema 定义 * @param path - 变量路径,如 "a.b.c" * @param schema - 根 JSON Schema * @returns 路径对应的 schema,如果不存在则返回 undefined */ private getSchemaForPath; /** * 从 schema 获取默认值 * 优先级:default > type > undefined * @param schema - 字段的 JSON Schema * @returns 默认值 */ private getDefaultValueFromSchema; } interface PluginManifest { name: string; version?: string; displayName?: string; form?: { refType?: 'config' | 'action'; schema?: unknown; }; [key: string]: unknown; } declare class PluginNotFoundError extends Error { readonly pluginKey: string; constructor(pluginKey: string); } declare class PluginLoadError extends Error { constructor(pluginKey: string, reason: string); } declare class PluginLoaderService { private readonly logger; private readonly pluginInstances; /** 记录每个插件的加载版本(时间戳),用于 ESM 缓存绕过 */ private readonly pluginVersions; /** 缓存插件的 manifest.json */ private readonly manifestCache; /** * 从入口路径向上查找包根目录(包含 package.json 的目录) */ private findPackageRoot; /** * 读取并缓存 manifest */ getManifest(pluginKey: string): PluginManifest | null; /** * 检查插件是否需要 config(form.refType === 'config') */ isConfigRequired(pluginKey: string): boolean; loadPlugin(pluginKey: string, config?: unknown): Promise; /** * 创建插件实例(内部方法) */ private createPluginInstance; isPluginInstalled(pluginKey: string): boolean; /** * 清除插件缓存 * - 清除应用层 pluginInstances 缓存 * - 清除 manifest 缓存 * - 清除 Node.js CJS 模块缓存(require.cache) * - 更新版本号,下次 import 时绕过 ESM 缓存 * @param pluginKey - 插件标识,不传则清除所有 */ clearCache(pluginKey?: string): void; /** * 清除 CJS 模块缓存 */ private clearNodeModuleCache; /** * 递归清除子模块缓存 */ private clearModuleAndChildren; /** * 强制重新加载插件 * @param pluginKey - 插件标识 */ reloadPlugin(pluginKey: string): Promise; } declare class CapabilityNotFoundError extends Error { readonly capabilityId: string; constructor(capabilityId: string); } declare class ActionNotFoundError extends Error { readonly pluginKey: string; readonly actionName: string; constructor(pluginKey: string, actionName: string); } interface ParamDiagnostic { field: string; reason: 'not_provided' | 'empty_value'; detail: string; } declare class RequiredParamMissingError extends Error { readonly capabilityName: string; readonly diagnostics: ParamDiagnostic[]; constructor(capabilityName: string, diagnostics: ParamDiagnostic[]); } interface CapabilityExecutor { /** * 调用 capability(始终返回 Promise) * - unary action: 直接返回结果 * - stream action: 内部聚合所有 chunk 后返回 */ call(actionName: string, input: unknown, context?: Partial): Promise; /** * 流式调用 capability,返回原始流 * - 返回原始 AsyncIterable * - 如果 action 是 unary,包装为单次 yield */ callStream(actionName: string, input: unknown, context?: Partial): AsyncIterable; /** * 流式调用 capability,返回带事件协议的流(推荐) * - 返回 StreamEvent 类型的 AsyncIterable * - 支持 data/done/error 三种事件类型 * - Controller 层应优先使用此方法实现边收边发 */ callStreamWithEvents(actionName: string, input: unknown, context?: Partial): AsyncIterable>; /** * 检查 action 是否为流式 */ isStream(actionName: string): Promise; } interface CapabilityModuleOptions { /** 能力配置目录路径,默认 server/capabilities */ capabilitiesDir?: string; /** 是否启用文件监听(热更新),默认 false */ enableWatching?: boolean; /** 文件变更防抖时间(ms),默认 300 */ watchDebounce?: number; } declare class CapabilityService implements OnModuleInit, OnModuleDestroy { private readonly requestContextService; private readonly httpClientFactory; private readonly pluginLoaderService; private readonly templateEngineService; private readonly telemetryService; private readonly logger; private readonly capabilities; /** 文件路径到 capability id 的映射,用于文件删除时查找 */ private readonly filePathToId; private capabilitiesDir; private fileWatcher; private options; constructor(requestContextService: RequestContextService, httpClientFactory: HttpClientFactory, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService, telemetryService: TelemetryService); /** * 设置模块配置 */ setOptions(options: CapabilityModuleOptions): void; setCapabilitiesDir(dir: string): void; onModuleInit(): Promise; onModuleDestroy(): Promise; /** * 启动文件监听(沙箱环境自动调用) */ startWatching(): void; /** * 停止文件监听 */ stopWatching(): void; /** * 重新加载所有能力配置 */ reloadAllCapabilities(): Promise; private handleFileAdd; private handleFileChange; private handleFileUnlink; /** * 从文件加载单个能力配置 */ private loadCapabilityFromFile; /** * 重新加载单个能力配置 */ private reloadCapabilityFromFile; /** * 根据文件路径移除能力配置 */ private removeCapabilityByFile; private loadCapabilities; listCapabilities(): CapabilityConfig[]; getCapability(capabilityId: string): CapabilityConfig | null; load(capabilityId: string): CapabilityExecutor; /** * 使用传入的配置加载能力执行器 * 用于 debug 场景,支持用户传入自定义配置 */ loadWithConfig(config: CapabilityConfig): CapabilityExecutor; private createExecutor; /** * 加载插件实例并解析参数 * 根据 manifest 的 form.refType 决定 formValue 的消费方式 */ private loadPluginAndResolveParams; /** * 校验调用方传入的 input 是否满足 paramsSchema.required 约束。 * * 注意:校验发生在模板替换之前。paramsSchema.required 声明的是调用方需要传哪些变量 * (它们会被 formValue 中的 {{input.xxx}} 引用),不是 resolve 后的 formValue key。 * * Debug 调用(isDebug=true)跳过校验:开发者可能在 paramSchema 里声明了字段但表单 * 里并未通过 {{input.xxx}} 实际引用,此时 required 校验会误报;debug 阶段交由 * 插件自身的 zod schema 兜底即可。 * * 诊断原因: * not_provided — input 中完全没有该字段(key 不存在 / undefined / null),调用方未传 * empty_value — 调用方传了值但为空(空串/空数组),需要检查数据来源 */ private validateRequiredParams; /** * 检查 action 是否为流式 */ private checkIsStream; /** * 执行 capability(始终返回 Promise) * - unary action: 直接返回结果 * - stream action: 内部聚合所有 chunk 后返回 */ private executeCall; /** * 流式执行 capability * - stream action: 返回原始 AsyncIterable * - unary action: 包装为单次 yield */ private executeCallStream; /** * 流式执行 capability,返回带事件协议的流 * - 优先使用 pluginInstance.runStreamWithEvents * - 如果插件不支持,则包装 runStream/run 为 StreamEvent */ private executeCallStreamWithEvents; /** * 上报调用事件(fire-and-forget) */ private reportCallEvent; /** * 从错误对象提取错误信息 * 支持 PluginError 和 RateLimitError * @param error - 捕获到的错误 * @param pluginKey - 插件 key,用于获取 displayName 格式化 PluginError 消息 */ private extractErrorInfo; private buildActionContext; /** * 为指定插件创建独立的 HttpClient 实例 * 自动添加 x-plugin-key header */ private createPluginHttpClient; /** * 将 HttpClient 包装为受保护的 PlatformHttpClient * 只暴露请求方法,不暴露 interceptors */ private wrapAsProtectedClient; private getUserContext; } interface DebugRequestBody { action?: string; params?: Record; capability?: CapabilityConfig; } declare class DebugController { private readonly capabilityService; private readonly pluginLoaderService; private readonly templateEngineService; private readonly logger; constructor(capabilityService: CapabilityService, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService); list(res: Response): void; /** * 获取 capability 配置 * 优先使用 body.capability,否则从服务获取 */ private getCapabilityConfig; /** * 获取 action 名称 * 优先使用传入的 action,否则使用插件第一个 action */ private getActionName; debug(capabilityId: string, body: DebugRequestBody, res: Response): Promise; /** * 构建错误响应 */ private buildErrorResponse; debugStream(capabilityId: string, body: DebugRequestBody, res: Response): Promise; } interface ExecuteRequestBody { action: string; params: Record; } declare class WebhookController { private readonly capabilityService; private readonly logger; constructor(capabilityService: CapabilityService); list(res: Response): void; execute(capabilityId: string, body: ExecuteRequestBody, res: Response): Promise; /** * 构建错误响应 */ private buildErrorResponse; executeStream(capabilityId: string, body: ExecuteRequestBody, res: Response): Promise; } declare class CapabilityModule { static forRoot(options?: CapabilityModuleOptions): DynamicModule; } /** * Migration Adaptor * * 用于迁移老版本 capability 调用代码,将新版本的返回结果包装为老版本的 Response 结构 */ /** * 失败输出结构 */ interface FailureOutput { response: { status: { /** 协议层返回码(如 HTTP 状态码) */ protocolStatusCode: string; /** 业务应用状态码 */ appStatusCode: string; }; /** 返回体(JSON 字符串形式) */ body: string; }; } /** * 老版本 capability 调用的 Response 结构 * * 注意:output 使用 any 类型以简化迁移代码,避免类型断言 */ interface MigrationResponse { /** 当 code=0 时表示执行成功,当 code!=0 时表示执行失败 */ code: number; data?: { /** 执行成功时的输出结果(any 类型,兼容迁移场景) */ output?: any; /** 执行结果,'success' 或 'error' */ outcome?: 'success' | 'error'; /** 执行失败时的输出结果 */ failureOutput?: FailureOutput; }; /** 发生错误时的错误信息 */ message?: string; } /** * 迁移适配器 * * 将 CapabilityService.load().call() 的返回结果包装为老版本的 Response 结构 * * @example * // 老代码 * const result = await generateTaskDescription(params); * * // 新代码 * const result = await migrationAdaptor( * this.capabilityService.load('ai_generate_task_description').call('run', params) * ); * * // result 结构 * // { * // code: 0, * // data: { * // output: { ... }, // 能力执行结果 * // outcome: 'success' * // } * // } */ declare function migrationAdaptor(promise: Promise): Promise; export { ActionNotFoundError, type ActionSchema, type CallEventDetails, type CallerType, type CapabilityConfig, type CapabilityExecutor, type CapabilityListItem, CapabilityModule, type CapabilityModuleOptions, CapabilityNotFoundError, CapabilityService, DebugController, type DebugExecuteResponseData, type DebugInfo, type ErrorCode, ErrorCodes, type ErrorResponse, type EventType, type ExecuteResponseData, type FailureOutput, type JSONSchema, type ListResponseData, type MigrationResponse, type ParamDiagnostic, type PluginActionContext, type PluginInstance, PluginLoadError, PluginLoaderService, type PluginManifest, PluginNotFoundError, type PluginPackage, RequiredParamMissingError, type ResourceEvent, type StreamContentResponse, type StreamDoneMetadata, type StreamError, type StreamErrorResponse, type StreamEvent, type StreamResponse, type SuccessResponse, TelemetryService, TemplateEngineService, type UserContext, WebhookController, migrationAdaptor };