@lark-apaas/nestjs-capability 0.0.1-alpha.3 → 0.0.1-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/controllers/debug.controller.ts","../src/controllers/webhook.controller.ts","../src/capability.module.ts"],"sourcesContent":["export * from './interfaces';\nexport * from './services';\nexport * from './controllers';\nexport * from './capability.module';\n","import { Injectable } from '@nestjs/common';\n\n/**\n * 模板引擎服务\n *\n * 支持语法:\n * - expr: '{{' + selector + '}}'\n * - selector: 'input.' + ident | selector.ident\n * - ident: [a-zA-Z_]([a-zA-Z_0-9])*\n *\n * 示例:\n * - {{input.a}}\n * - {{input.a.b}}\n * - \"this is {{input.a.b}}\"\n *\n * 求值规则:\n * - 如果整个字符串是单个表达式,保留原始类型\n * - 如果是字符串插值(多个表达式或混合内容),返回字符串\n * - 如果变量不存在,返回原始表达式\n */\n@Injectable()\nexport class TemplateEngineService {\n // 匹配 {{input.xxx}} 或 {{input.xxx.yyy}} 表达式\n private readonly EXPR_REGEX = /\\{\\{input\\.([a-zA-Z_][a-zA-Z_0-9]*(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)*)\\}\\}/g;\n // 匹配整串单个表达式\n private readonly WHOLE_STRING_EXPR_REGEX = /^\\{\\{input\\.([a-zA-Z_][a-zA-Z_0-9]*(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)*)\\}\\}$/;\n\n resolve(template: unknown, input: Record<string, unknown>): unknown {\n if (typeof template === 'string') {\n return this.resolveString(template, input);\n }\n\n if (Array.isArray(template)) {\n return template.map(item => this.resolve(item, input));\n }\n\n if (template !== null && typeof template === 'object') {\n return this.resolveObject(template as Record<string, unknown>, input);\n }\n\n return template;\n }\n\n private resolveString(template: string, input: Record<string, unknown>): unknown {\n // 情况1: 整串是单个表达式 → 保留原始类型\n const wholeMatch = template.match(this.WHOLE_STRING_EXPR_REGEX);\n if (wholeMatch) {\n const path = wholeMatch[1];\n const value = this.getValueByPath(input, path);\n // 变量不存在,返回原始表达式\n return value !== undefined ? value : template;\n }\n\n // 情况2: 字符串插值 → 返回字符串\n // 重置正则的 lastIndex(因为使用了 g 标志)\n this.EXPR_REGEX.lastIndex = 0;\n\n // 检查是否有任何表达式\n if (!this.EXPR_REGEX.test(template)) {\n return template;\n }\n\n // 重置并进行替换\n this.EXPR_REGEX.lastIndex = 0;\n const result = template.replace(this.EXPR_REGEX, (match, path) => {\n const value = this.getValueByPath(input, path);\n // 变量不存在,保留原始表达式\n if (value === undefined) {\n return match;\n }\n return String(value);\n });\n\n return result;\n }\n\n private resolveObject(\n template: Record<string, unknown>,\n input: Record<string, unknown>,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(template)) {\n result[key] = this.resolve(value, input);\n }\n\n return result;\n }\n\n private getValueByPath(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport class PluginNotFoundError extends Error {\n constructor(pluginID: string) {\n super(`Plugin not found: ${pluginID}`);\n this.name = 'PluginNotFoundError';\n }\n}\n\nexport class PluginLoadError extends Error {\n constructor(pluginID: string, reason: string) {\n super(`Failed to load plugin ${pluginID}: ${reason}`);\n this.name = 'PluginLoadError';\n }\n}\n\n@Injectable()\nexport class PluginLoaderService {\n private readonly logger = new Logger(PluginLoaderService.name);\n private readonly pluginInstances = new Map<string, PluginInstance>();\n\n async loadPlugin(pluginID: string): Promise<PluginInstance> {\n const cached = this.pluginInstances.get(pluginID);\n if (cached) {\n this.logger.debug(`Using cached plugin instance: ${pluginID}`);\n return cached;\n }\n\n this.logger.log(`Loading plugin: ${pluginID}`);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const pluginPackage = (await import(pluginID)).default as PluginPackage;\n\n if (typeof pluginPackage.create !== 'function') {\n throw new PluginLoadError(pluginID, 'Plugin does not export create() function');\n }\n\n const instance = pluginPackage.create();\n this.pluginInstances.set(pluginID, instance);\n\n this.logger.log(`Plugin loaded successfully: ${pluginID}`);\n return instance;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new PluginNotFoundError(pluginID);\n }\n throw new PluginLoadError(\n pluginID,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n isPluginInstalled(pluginID: string): boolean {\n try {\n require.resolve(pluginID);\n return true;\n } catch {\n return false;\n }\n }\n\n clearCache(pluginID?: string): void {\n if (pluginID) {\n this.pluginInstances.delete(pluginID);\n this.logger.log(`Cleared cache for plugin: ${pluginID}`);\n } else {\n this.pluginInstances.clear();\n this.logger.log('Cleared all plugin caches');\n }\n }\n}\n","import { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { CapabilityConfig, PluginActionContext, UserContext } from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\n\nexport class CapabilityNotFoundError extends Error {\n constructor(capabilityId: string) {\n super(`Capability not found: ${capabilityId}`);\n this.name = 'CapabilityNotFoundError';\n }\n}\n\nexport class ActionNotFoundError extends Error {\n constructor(pluginID: string, actionName: string) {\n super(`Action '${actionName}' not found in plugin ${pluginID}`);\n this.name = 'ActionNotFoundError';\n }\n}\n\nexport interface CapabilityExecutor {\n /**\n * 调用 capability(始终返回 Promise)\n * - unary action: 直接返回结果\n * - stream action: 内部聚合所有 chunk 后返回\n */\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n\n /**\n * 流式调用 capability\n * - 返回原始 AsyncIterable\n * - 如果 action 是 unary,包装为单次 yield\n */\n callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;\n\n /**\n * 检查 action 是否为流式\n */\n isStream(actionName: string): Promise<boolean>;\n}\n\nexport interface CapabilityModuleOptions {\n capabilitiesDir?: string;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit {\n private readonly logger = new Logger(CapabilityService.name);\n private readonly capabilities = new Map<string, CapabilityConfig>();\n private capabilitiesDir: string;\n\n constructor(\n private readonly requestContextService: RequestContextService,\n @Inject(PLATFORM_HTTP_CLIENT) private readonly httpClient: PlatformHttpClient,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {\n this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n }\n\n setCapabilitiesDir(dir: string): void {\n this.capabilitiesDir = dir;\n }\n\n async onModuleInit(): Promise<void> {\n await this.loadCapabilities();\n }\n\n private async loadCapabilities(): Promise<void> {\n this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);\n\n if (!fs.existsSync(this.capabilitiesDir)) {\n this.logger.warn(`Capabilities directory not found: ${this.capabilitiesDir}`);\n return;\n }\n\n const files = fs.readdirSync(this.capabilitiesDir).filter(f => f.endsWith('.json'));\n\n for (const file of files) {\n try {\n const filePath = path.join(this.capabilitiesDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n const config = JSON.parse(content) as CapabilityConfig;\n\n if (!config.id) {\n this.logger.warn(`Skipping capability without id: ${file}`);\n continue;\n }\n\n this.capabilities.set(config.id, config);\n this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n } catch (error) {\n this.logger.error(`Failed to load capability from ${file}:`, error);\n }\n }\n\n this.logger.log(`Loaded ${this.capabilities.size} capabilities`);\n }\n\n listCapabilities(): CapabilityConfig[] {\n return Array.from(this.capabilities.values());\n }\n\n getCapability(capabilityId: string): CapabilityConfig | null {\n return this.capabilities.get(capabilityId) ?? null;\n }\n\n load(capabilityId: string): CapabilityExecutor {\n const config = this.capabilities.get(capabilityId);\n if (!config) {\n throw new CapabilityNotFoundError(capabilityId);\n }\n\n return this.createExecutor(config);\n }\n\n /**\n * 使用传入的配置加载能力执行器\n * 用于 debug 场景,支持用户传入自定义配置\n */\n loadWithConfig(config: CapabilityConfig): CapabilityExecutor {\n return this.createExecutor(config);\n }\n\n private createExecutor(config: CapabilityConfig): CapabilityExecutor {\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCall(config, actionName, input, contextOverride);\n },\n\n callStream: (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCallStream(config, actionName, input, contextOverride);\n },\n\n isStream: async (actionName: string) => {\n return this.checkIsStream(config, actionName);\n },\n };\n }\n\n /**\n * 检查 action 是否为流式\n */\n private async checkIsStream(config: CapabilityConfig, actionName: string): Promise<boolean> {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n return pluginInstance.isStreamAction?.(actionName) ?? false;\n }\n\n /**\n * 执行 capability(始终返回 Promise)\n * - unary action: 直接返回结果\n * - stream action: 内部聚合所有 chunk 后返回\n */\n private async executeCall(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): Promise<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n isStream,\n });\n\n let result: unknown;\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:聚合所有 chunk\n const chunks: unknown[] = [];\n for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {\n chunks.push(chunk);\n }\n // 使用插件的聚合方法,或默认返回 chunks 数组\n result = pluginInstance.aggregate\n ? pluginInstance.aggregate(actionName, chunks)\n : chunks;\n } else {\n // 非流式 action:直接调用\n result = await pluginInstance.run(actionName, context, resolvedParams);\n }\n\n this.logger.log({\n message: 'Capability executed successfully',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n\n return result;\n } catch (error) {\n this.logger.error({\n message: 'Capability execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n /**\n * 流式执行 capability\n * - stream action: 返回原始 AsyncIterable\n * - unary action: 包装为单次 yield\n */\n private async *executeCallStream(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): AsyncIterable<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginID);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginID, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n this.logger.log({\n message: 'Executing capability (stream)',\n capabilityId: config.id,\n action: actionName,\n pluginID: config.pluginID,\n isStream,\n });\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:透传 AsyncIterable\n yield* pluginInstance.runStream(actionName, context, resolvedParams);\n } else {\n // 非流式 action:包装为单次 yield\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n yield result;\n }\n\n this.logger.log({\n message: 'Capability stream completed',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n } catch (error) {\n this.logger.error({\n message: 'Capability stream execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n private buildActionContext(override?: Partial<PluginActionContext>): PluginActionContext {\n return {\n logger: this.logger,\n httpClient: this.httpClient,\n userContext: override?.userContext ?? this.getUserContext(),\n };\n }\n\n private getUserContext(): UserContext {\n const ctx = this.requestContextService.getContext();\n return {\n userId: ctx?.userId ?? '',\n tenantId: ctx?.tenantId ?? '',\n };\n }\n}\n","import {\n Controller,\n Post,\n Get,\n Param,\n Body,\n Res,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport type { Response } from 'express';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginLoaderService, PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\nimport type { CapabilityConfig } from '../interfaces';\n\ninterface DebugRequestBody {\n action?: string;\n params?: Record<string, unknown>;\n capability?: CapabilityConfig;\n}\n\ninterface DebugResponse {\n code: number;\n message: string;\n data: unknown;\n debug?: {\n capabilityConfig: unknown;\n resolvedParams: unknown;\n duration: number;\n pluginID: string;\n action: string;\n };\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: Array<{\n id: string;\n name: string;\n pluginID: string;\n pluginVersion: string;\n }>;\n}\n\n@Controller('__innerapi__/capability')\nexport class DebugController {\n constructor(\n private readonly capabilityService: CapabilityService,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n /**\n * 获取 capability 配置\n * 优先使用 body.capability,否则从服务获取\n */\n private getCapabilityConfig(\n capabilityId: string,\n bodyCapability?: CapabilityConfig,\n ): CapabilityConfig {\n if (bodyCapability) {\n return bodyCapability;\n }\n\n const config = this.capabilityService.getCapability(capabilityId);\n if (!config) {\n throw new HttpException(\n {\n code: 1,\n message: `Capability not found: ${capabilityId}`,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n return config;\n }\n\n /**\n * 获取 action 名称\n * 优先使用传入的 action,否则使用插件第一个 action\n */\n private async getActionName(pluginID: string, bodyAction?: string): Promise<string> {\n if (bodyAction) {\n return bodyAction;\n }\n\n const pluginInstance = await this.pluginLoaderService.loadPlugin(pluginID);\n const actions = pluginInstance.listActions();\n\n if (actions.length === 0) {\n throw new HttpException(\n {\n code: 1,\n message: `Plugin ${pluginID} has no actions`,\n error: 'NO_ACTIONS',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n return actions[0];\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: DebugRequestBody,\n ): Promise<DebugResponse> {\n const startTime = Date.now();\n const params = body.params ?? {};\n\n const config = this.getCapabilityConfig(capabilityId, body.capability);\n const action = await this.getActionName(config.pluginID, body.action);\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n params,\n );\n\n try {\n const result = await this.capabilityService\n .loadWithConfig(config)\n .call(action, params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n debug: {\n capabilityConfig: config,\n resolvedParams,\n duration: Date.now() - startTime,\n pluginID: config.pluginID,\n action,\n },\n };\n } catch (error) {\n const duration = Date.now() - startTime;\n\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n debug: { duration },\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID, action },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n debug: { duration, pluginID: config.pluginID, action },\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n debug: {\n duration,\n pluginID: config.pluginID,\n action,\n resolvedParams,\n },\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n\n @Post('debug/:capability_id/stream')\n async debugStream(\n @Param('capability_id') capabilityId: string,\n @Body() body: DebugRequestBody,\n @Res() res: Response,\n ): Promise<void> {\n const params = body.params ?? {};\n\n // 设置 SSE 响应头\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const config = this.getCapabilityConfig(capabilityId, body.capability);\n const action = await this.getActionName(config.pluginID, body.action);\n\n const capability = this.capabilityService.loadWithConfig(config);\n const stream = capability.callStream(action, params);\n\n for await (const chunk of stream) {\n res.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n\n // 发送结束标记\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n // 错误时发送错误信息\n const message = error instanceof Error ? error.message : String(error);\n let errorCode = 'EXECUTION_ERROR';\n\n if (error instanceof CapabilityNotFoundError) {\n errorCode = 'CAPABILITY_NOT_FOUND';\n } else if (error instanceof PluginNotFoundError) {\n errorCode = 'PLUGIN_NOT_FOUND';\n } else if (error instanceof ActionNotFoundError) {\n errorCode = 'ACTION_NOT_FOUND';\n } else if (error instanceof HttpException) {\n const response = error.getResponse() as { error?: string };\n errorCode = response.error ?? 'EXECUTION_ERROR';\n }\n\n res.write(`data: ${JSON.stringify({ error: message, code: errorCode })}\\n\\n`);\n } finally {\n res.end();\n }\n }\n}\n","import {\n Controller,\n Get,\n Post,\n Param,\n Body,\n Res,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport type { Response } from 'express';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\ninterface ExecuteResponse {\n code: number;\n message: string;\n data: unknown;\n}\n\ninterface CapabilityInfo {\n id: string;\n name: string;\n description: string;\n pluginID: string;\n pluginVersion: string;\n}\n\ninterface ListResponse {\n code: number;\n message: string;\n data: CapabilityInfo[];\n}\n\n@Controller('api/capability')\nexport class WebhookController {\n constructor(private readonly capabilityService: CapabilityService) {}\n\n @Get('list')\n list(): ListResponse {\n const capabilities = this.capabilityService.listCapabilities();\n return {\n code: 0,\n message: 'success',\n data: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n description: c.description,\n pluginID: c.pluginID,\n pluginVersion: c.pluginVersion,\n })),\n };\n }\n\n @Post(':capability_id')\n async execute(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<ExecuteResponse> {\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n code: 0,\n message: 'success',\n data: result,\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'PLUGIN_NOT_FOUND',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n code: 1,\n message: error.message,\n error: 'ACTION_NOT_FOUND',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n code: 1,\n message: error instanceof Error ? error.message : String(error),\n error: 'EXECUTION_ERROR',\n },\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n\n @Post(':capability_id/stream')\n async executeStream(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n @Res() res: Response,\n ): Promise<void> {\n // 设置 SSE 响应头\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const capability = this.capabilityService.load(capabilityId);\n const stream = capability.callStream(body.action, body.params);\n\n for await (const chunk of stream) {\n res.write(`data: ${JSON.stringify(chunk)}\\n\\n`);\n }\n\n // 发送结束标记\n res.write('data: [DONE]\\n\\n');\n } catch (error) {\n // 错误时发送错误信息\n const message = error instanceof Error ? error.message : String(error);\n let errorCode = 'EXECUTION_ERROR';\n\n if (error instanceof CapabilityNotFoundError) {\n errorCode = 'CAPABILITY_NOT_FOUND';\n } else if (error instanceof PluginNotFoundError) {\n errorCode = 'PLUGIN_NOT_FOUND';\n } else if (error instanceof ActionNotFoundError) {\n errorCode = 'ACTION_NOT_FOUND';\n }\n\n res.write(`data: ${JSON.stringify({ error: message, code: errorCode })}\\n\\n`);\n } finally {\n res.end();\n }\n }\n}\n","import { Module, DynamicModule, Type } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n CapabilityService,\n PluginLoaderService,\n TemplateEngineService,\n type CapabilityModuleOptions,\n} from './services';\n\nconst CAPABILITY_OPTIONS = Symbol('CAPABILITY_OPTIONS');\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\nfunction getControllers(): Type[] {\n const controllers: Type[] = [WebhookController];\n if (isDevelopment) {\n controllers.push(DebugController);\n }\n return controllers;\n}\n\n@Module({\n controllers: getControllers(),\n providers: [CapabilityService, PluginLoaderService, TemplateEngineService],\n exports: [CapabilityService],\n})\nexport class CapabilityModule {\n static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n return {\n module: CapabilityModule,\n controllers: getControllers(),\n providers: [\n {\n provide: CAPABILITY_OPTIONS,\n useValue: options ?? {},\n },\n {\n provide: CapabilityService,\n useFactory: (\n requestContextService: RequestContextService,\n httpClient: any,\n pluginLoader: PluginLoaderService,\n templateEngine: TemplateEngineService,\n moduleOptions: CapabilityModuleOptions,\n ) => {\n const service = new CapabilityService(\n requestContextService,\n httpClient,\n pluginLoader,\n templateEngine,\n );\n if (moduleOptions?.capabilitiesDir) {\n service.setCapabilitiesDir(moduleOptions.capabilitiesDir);\n }\n return service;\n },\n inject: [\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n PluginLoaderService,\n TemplateEngineService,\n CAPABILITY_OPTIONS,\n ],\n },\n PluginLoaderService,\n TemplateEngineService,\n ],\n exports: [CapabilityService],\n };\n }\n}\n"],"mappings":"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","names":["TemplateEngineService","EXPR_REGEX","WHOLE_STRING_EXPR_REGEX","resolve","template","input","resolveString","Array","isArray","map","item","resolveObject","wholeMatch","match","path","value","getValueByPath","undefined","lastIndex","test","result","replace","String","key","Object","entries","obj","keys","split","current","import_common","PluginNotFoundError","Error","pluginID","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","loadPlugin","cached","get","debug","log","pluginPackage","default","create","instance","set","error","code","message","String","isPluginInstalled","require","resolve","clearCache","delete","clear","import_common","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginID","actionName","CapabilityService","logger","Logger","capabilities","Map","capabilitiesDir","requestContextService","httpClient","pluginLoaderService","templateEngineService","join","process","cwd","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","log","existsSync","warn","files","readdirSync","filter","f","endsWith","file","filePath","content","readFileSync","config","JSON","parse","id","set","error","size","listCapabilities","Array","from","values","getCapability","get","load","createExecutor","loadWithConfig","call","input","contextOverride","executeCall","callStream","executeCallStream","isStream","checkIsStream","pluginInstance","loadPlugin","hasAction","isStreamAction","startTime","Date","now","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","runStream","chunks","chunk","push","aggregate","run","duration","String","override","userContext","getUserContext","ctx","getContext","userId","tenantId","import_common","DebugController","capabilityService","pluginLoaderService","templateEngineService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","pluginID","pluginVersion","getCapabilityConfig","capabilityId","bodyCapability","config","getCapability","HttpException","error","HttpStatus","NOT_FOUND","getActionName","bodyAction","pluginInstance","loadPlugin","actions","listActions","length","BAD_REQUEST","debug","body","startTime","Date","now","params","capability","action","resolvedParams","resolve","formValue","result","loadWithConfig","call","capabilityConfig","duration","CapabilityNotFoundError","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","Error","String","debugStream","res","setHeader","stream","callStream","chunk","write","JSON","stringify","errorCode","response","getResponse","end","import_common","WebhookController","capabilityService","list","capabilities","listCapabilities","code","message","data","map","c","id","name","description","pluginID","pluginVersion","execute","capabilityId","body","result","load","call","action","params","error","CapabilityNotFoundError","HttpException","HttpStatus","NOT_FOUND","PluginNotFoundError","INTERNAL_SERVER_ERROR","ActionNotFoundError","BAD_REQUEST","Error","String","executeStream","res","setHeader","capability","stream","callStream","chunk","write","JSON","stringify","errorCode","end","import_common","import_nestjs_common","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClient","pluginLoader","templateEngine","moduleOptions","service","capabilitiesDir","setCapabilitiesDir","inject","RequestContextService","PLATFORM_HTTP_CLIENT","PluginLoaderService","TemplateEngineService","exports"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/interfaces/error-codes.ts","../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/controllers/debug.controller.ts","../src/controllers/webhook.controller.ts","../src/capability.module.ts"],"sourcesContent":["export * from './interfaces';\nexport * from './services';\nexport * from './controllers';\nexport * from './capability.module';\n","/**\n * Capability 模块错误码\n */\nexport const ErrorCodes = {\n /** 成功 */\n SUCCESS: '0',\n /** 能力不存在 */\n CAPABILITY_NOT_FOUND: 'k_ec_cap_001',\n /** 插件不存在 */\n PLUGIN_NOT_FOUND: 'k_ec_cap_002',\n /** Action 不存在 */\n ACTION_NOT_FOUND: 'k_ec_cap_003',\n /** 参数验证失败 */\n PARAMS_VALIDATION_ERROR: 'k_ec_cap_004',\n /** 执行失败 */\n EXECUTION_ERROR: 'k_ec_cap_005',\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n","import { Injectable } from '@nestjs/common';\n\n/**\n * 模板引擎服务\n *\n * 支持语法:\n * - expr: '{{' + selector + '}}'\n * - selector: 'input.' + ident | selector.ident\n * - ident: [a-zA-Z_]([a-zA-Z_0-9])*\n *\n * 示例:\n * - {{input.a}}\n * - {{input.a.b}}\n * - \"this is {{input.a.b}}\"\n *\n * 求值规则:\n * - 如果整个字符串是单个表达式,保留原始类型\n * - 如果是字符串插值(多个表达式或混合内容),返回字符串\n * - 如果变量不存在,返回原始表达式\n */\n@Injectable()\nexport class TemplateEngineService {\n // 匹配 {{input.xxx}} 或 {{input.xxx.yyy}} 表达式\n private readonly EXPR_REGEX = /\\{\\{input\\.([a-zA-Z_][a-zA-Z_0-9]*(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)*)\\}\\}/g;\n // 匹配整串单个表达式\n private readonly WHOLE_STRING_EXPR_REGEX = /^\\{\\{input\\.([a-zA-Z_][a-zA-Z_0-9]*(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)*)\\}\\}$/;\n\n resolve(template: unknown, input: Record<string, unknown>): unknown {\n if (typeof template === 'string') {\n return this.resolveString(template, input);\n }\n\n if (Array.isArray(template)) {\n return template.map(item => this.resolve(item, input));\n }\n\n if (template !== null && typeof template === 'object') {\n return this.resolveObject(template as Record<string, unknown>, input);\n }\n\n return template;\n }\n\n private resolveString(template: string, input: Record<string, unknown>): unknown {\n // 情况1: 整串是单个表达式 → 保留原始类型\n const wholeMatch = template.match(this.WHOLE_STRING_EXPR_REGEX);\n if (wholeMatch) {\n const path = wholeMatch[1];\n const value = this.getValueByPath(input, path);\n // 变量不存在,返回原始表达式\n return value !== undefined ? value : template;\n }\n\n // 情况2: 字符串插值 → 返回字符串\n // 重置正则的 lastIndex(因为使用了 g 标志)\n this.EXPR_REGEX.lastIndex = 0;\n\n // 检查是否有任何表达式\n if (!this.EXPR_REGEX.test(template)) {\n return template;\n }\n\n // 重置并进行替换\n this.EXPR_REGEX.lastIndex = 0;\n const result = template.replace(this.EXPR_REGEX, (match, path) => {\n const value = this.getValueByPath(input, path);\n // 变量不存在,保留原始表达式\n if (value === undefined) {\n return match;\n }\n return String(value);\n });\n\n return result;\n }\n\n private resolveObject(\n template: Record<string, unknown>,\n input: Record<string, unknown>,\n ): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(template)) {\n result[key] = this.resolve(value, input);\n }\n\n return result;\n }\n\n private getValueByPath(obj: Record<string, unknown>, path: string): unknown {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport class PluginNotFoundError extends Error {\n constructor(pluginKey: string) {\n super(`Plugin not found: ${pluginKey}`);\n this.name = 'PluginNotFoundError';\n }\n}\n\nexport class PluginLoadError extends Error {\n constructor(pluginKey: string, reason: string) {\n super(`Failed to load plugin ${pluginKey}: ${reason}`);\n this.name = 'PluginLoadError';\n }\n}\n\n@Injectable()\nexport class PluginLoaderService {\n private readonly logger = new Logger(PluginLoaderService.name);\n private readonly pluginInstances = new Map<string, PluginInstance>();\n\n async loadPlugin(pluginKey: string): Promise<PluginInstance> {\n const cached = this.pluginInstances.get(pluginKey);\n if (cached) {\n this.logger.debug(`Using cached plugin instance: ${pluginKey}`);\n return cached;\n }\n\n this.logger.log(`Loading plugin: ${pluginKey}`);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const pluginPackage = (await import(pluginKey)).default as PluginPackage;\n\n if (typeof pluginPackage.create !== 'function') {\n throw new PluginLoadError(pluginKey, 'Plugin does not export create() function');\n }\n\n const instance = pluginPackage.create();\n this.pluginInstances.set(pluginKey, instance);\n\n this.logger.log(`Plugin loaded successfully: ${pluginKey}`);\n return instance;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'MODULE_NOT_FOUND') {\n throw new PluginNotFoundError(pluginKey);\n }\n throw new PluginLoadError(\n pluginKey,\n error instanceof Error ? error.message : String(error),\n );\n }\n }\n\n isPluginInstalled(pluginKey: string): boolean {\n try {\n require.resolve(pluginKey);\n return true;\n } catch {\n return false;\n }\n }\n\n clearCache(pluginKey?: string): void {\n if (pluginKey) {\n this.pluginInstances.delete(pluginKey);\n this.logger.log(`Cleared cache for plugin: ${pluginKey}`);\n } else {\n this.pluginInstances.clear();\n this.logger.log('Cleared all plugin caches');\n }\n }\n}\n","import { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type {\n CapabilityConfig,\n PluginActionContext,\n UserContext,\n StreamEvent,\n} from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\n\nexport class CapabilityNotFoundError extends Error {\n constructor(capabilityId: string) {\n super(`Capability not found: ${capabilityId}`);\n this.name = 'CapabilityNotFoundError';\n }\n}\n\nexport class ActionNotFoundError extends Error {\n constructor(pluginKey: string, actionName: string) {\n super(`Action '${actionName}' not found in plugin ${pluginKey}`);\n this.name = 'ActionNotFoundError';\n }\n}\n\nexport interface CapabilityExecutor {\n /**\n * 调用 capability(始终返回 Promise)\n * - unary action: 直接返回结果\n * - stream action: 内部聚合所有 chunk 后返回\n */\n call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;\n\n /**\n * 流式调用 capability,返回原始流\n * - 返回原始 AsyncIterable\n * - 如果 action 是 unary,包装为单次 yield\n */\n callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;\n\n /**\n * 流式调用 capability,返回带事件协议的流(推荐)\n * - 返回 StreamEvent 类型的 AsyncIterable\n * - 支持 data/done/error 三种事件类型\n * - Controller 层应优先使用此方法实现边收边发\n */\n callStreamWithEvents(\n actionName: string,\n input: unknown,\n context?: Partial<PluginActionContext>,\n ): AsyncIterable<StreamEvent<unknown>>;\n\n /**\n * 检查 action 是否为流式\n */\n isStream(actionName: string): Promise<boolean>;\n}\n\nexport interface CapabilityModuleOptions {\n capabilitiesDir?: string;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit {\n private readonly logger = new Logger(CapabilityService.name);\n private readonly capabilities = new Map<string, CapabilityConfig>();\n private capabilitiesDir: string;\n\n constructor(\n private readonly requestContextService: RequestContextService,\n @Inject(PLATFORM_HTTP_CLIENT) private readonly httpClient: PlatformHttpClient,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {\n this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n }\n\n setCapabilitiesDir(dir: string): void {\n this.capabilitiesDir = dir;\n }\n\n async onModuleInit(): Promise<void> {\n await this.loadCapabilities();\n }\n\n private async loadCapabilities(): Promise<void> {\n this.logger.log(`Loading capabilities from ${this.capabilitiesDir}`);\n\n if (!fs.existsSync(this.capabilitiesDir)) {\n this.logger.warn(`Capabilities directory not found: ${this.capabilitiesDir}`);\n return;\n }\n\n const files = fs.readdirSync(this.capabilitiesDir).filter(f => f.endsWith('.json'));\n\n for (const file of files) {\n try {\n const filePath = path.join(this.capabilitiesDir, file);\n const content = fs.readFileSync(filePath, 'utf-8');\n const config = JSON.parse(content) as CapabilityConfig;\n\n if (!config.id) {\n this.logger.warn(`Skipping capability without id: ${file}`);\n continue;\n }\n\n this.capabilities.set(config.id, config);\n this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n } catch (error) {\n this.logger.error(`Failed to load capability from ${file}:`, error);\n }\n }\n\n this.logger.log(`Loaded ${this.capabilities.size} capabilities`);\n }\n\n listCapabilities(): CapabilityConfig[] {\n return Array.from(this.capabilities.values());\n }\n\n getCapability(capabilityId: string): CapabilityConfig | null {\n return this.capabilities.get(capabilityId) ?? null;\n }\n\n load(capabilityId: string): CapabilityExecutor {\n const config = this.capabilities.get(capabilityId);\n if (!config) {\n throw new CapabilityNotFoundError(capabilityId);\n }\n\n return this.createExecutor(config);\n }\n\n /**\n * 使用传入的配置加载能力执行器\n * 用于 debug 场景,支持用户传入自定义配置\n */\n loadWithConfig(config: CapabilityConfig): CapabilityExecutor {\n return this.createExecutor(config);\n }\n\n private createExecutor(config: CapabilityConfig): CapabilityExecutor {\n return {\n call: async (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCall(config, actionName, input, contextOverride);\n },\n\n callStream: (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCallStream(config, actionName, input, contextOverride);\n },\n\n callStreamWithEvents: (\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ) => {\n return this.executeCallStreamWithEvents(config, actionName, input, contextOverride);\n },\n\n isStream: async (actionName: string) => {\n return this.checkIsStream(config, actionName);\n },\n };\n }\n\n /**\n * 检查 action 是否为流式\n */\n private async checkIsStream(config: CapabilityConfig, actionName: string): Promise<boolean> {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginKey, actionName);\n }\n\n return pluginInstance.isStreamAction?.(actionName) ?? false;\n }\n\n /**\n * 执行 capability(始终返回 Promise)\n * - unary action: 直接返回结果\n * - stream action: 内部聚合所有 chunk 后返回\n */\n private async executeCall(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): Promise<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginKey, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n this.logger.log({\n message: 'Executing capability',\n capabilityId: config.id,\n action: actionName,\n pluginKey: config.pluginKey,\n isStream,\n });\n\n let result: unknown;\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:聚合所有 chunk\n const chunks: unknown[] = [];\n for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {\n chunks.push(chunk);\n }\n // 使用插件的聚合方法,或默认返回 chunks 数组\n result = pluginInstance.aggregate\n ? pluginInstance.aggregate(actionName, chunks)\n : chunks;\n } else {\n // 非流式 action:直接调用\n result = await pluginInstance.run(actionName, context, resolvedParams);\n }\n\n this.logger.log({\n message: 'Capability executed successfully',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n\n return result;\n } catch (error) {\n this.logger.error({\n message: 'Capability execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n /**\n * 流式执行 capability\n * - stream action: 返回原始 AsyncIterable\n * - unary action: 包装为单次 yield\n */\n private async *executeCallStream(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): AsyncIterable<unknown> {\n const startTime = Date.now();\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginKey, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n this.logger.log({\n message: 'Executing capability (stream)',\n capabilityId: config.id,\n action: actionName,\n pluginKey: config.pluginKey,\n isStream,\n });\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:透传 AsyncIterable\n yield* pluginInstance.runStream(actionName, context, resolvedParams);\n } else {\n // 非流式 action:包装为单次 yield\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n yield result;\n }\n\n this.logger.log({\n message: 'Capability stream completed',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n });\n } catch (error) {\n this.logger.error({\n message: 'Capability stream execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n throw error;\n }\n }\n\n /**\n * 流式执行 capability,返回带事件协议的流\n * - 优先使用 pluginInstance.runStreamWithEvents\n * - 如果插件不支持,则包装 runStream/run 为 StreamEvent\n */\n private async *executeCallStreamWithEvents(\n config: CapabilityConfig,\n actionName: string,\n input: unknown,\n contextOverride?: Partial<PluginActionContext>,\n ): AsyncIterable<StreamEvent<unknown>> {\n const startTime = Date.now();\n let chunkCount = 0;\n\n try {\n const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);\n\n if (!pluginInstance.hasAction(actionName)) {\n throw new ActionNotFoundError(config.pluginKey, actionName);\n }\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n input as Record<string, unknown>,\n );\n\n const context = this.buildActionContext(contextOverride);\n\n this.logger.log({\n message: 'Executing capability (streamWithEvents)',\n capabilityId: config.id,\n action: actionName,\n pluginKey: config.pluginKey,\n });\n\n // 优先使用 runStreamWithEvents\n if (pluginInstance.runStreamWithEvents) {\n yield* pluginInstance.runStreamWithEvents(actionName, context, resolvedParams);\n } else {\n // 回退:包装 runStream 或 run 为 StreamEvent\n const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n if (isStream && pluginInstance.runStream) {\n // 流式 action:包装每个 chunk 为 data 事件\n for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {\n chunkCount++;\n yield { type: 'data', data: chunk };\n }\n } else {\n // 非流式 action:包装结果为单个 data 事件\n const result = await pluginInstance.run(actionName, context, resolvedParams);\n chunkCount = 1;\n yield { type: 'data', data: result };\n }\n\n // 发送 done 事件\n yield {\n type: 'done',\n metadata: {\n chunks: chunkCount,\n duration: Date.now() - startTime,\n },\n };\n }\n\n this.logger.log({\n message: 'Capability streamWithEvents completed',\n capabilityId: config.id,\n action: actionName,\n duration: Date.now() - startTime,\n chunks: chunkCount,\n });\n } catch (error) {\n this.logger.error({\n message: 'Capability streamWithEvents execution failed',\n capabilityId: config.id,\n action: actionName,\n error: error instanceof Error ? error.message : String(error),\n duration: Date.now() - startTime,\n });\n\n // 发送 error 事件\n yield {\n type: 'error',\n error: {\n code: 'EXECUTION_ERROR',\n message: error instanceof Error ? error.message : String(error),\n },\n };\n }\n }\n\n private buildActionContext(override?: Partial<PluginActionContext>): PluginActionContext {\n return {\n logger: this.logger,\n httpClient: this.httpClient,\n userContext: override?.userContext ?? this.getUserContext(),\n };\n }\n\n private getUserContext(): UserContext {\n const ctx = this.requestContextService.getContext();\n return {\n userId: ctx?.userId ?? '',\n tenantId: ctx?.tenantId ?? '',\n };\n }\n}\n","import {\n Controller,\n Post,\n Get,\n Param,\n Body,\n Res,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport type { Response } from 'express';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginLoaderService, PluginNotFoundError } from '../services/plugin-loader.service';\nimport { TemplateEngineService } from '../services/template-engine.service';\nimport type {\n CapabilityConfig,\n SuccessResponse,\n ErrorResponse,\n DebugExecuteResponseData,\n ListResponseData,\n StreamContentResponse,\n StreamErrorResponse,\n} from '../interfaces';\nimport { ErrorCodes } from '../interfaces';\n\ninterface DebugRequestBody {\n action?: string;\n params?: Record<string, unknown>;\n capability?: CapabilityConfig;\n}\n\n@Controller('__innerapi__/capability')\nexport class DebugController {\n constructor(\n private readonly capabilityService: CapabilityService,\n private readonly pluginLoaderService: PluginLoaderService,\n private readonly templateEngineService: TemplateEngineService,\n ) {}\n\n @Get('list')\n list(): SuccessResponse<ListResponseData> {\n const capabilities = this.capabilityService.listCapabilities();\n\n return {\n status_code: ErrorCodes.SUCCESS,\n data: {\n capabilities: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginKey,\n pluginVersion: c.pluginVersion,\n })),\n },\n };\n }\n\n /**\n * 获取 capability 配置\n * 优先使用 body.capability,否则从服务获取\n */\n private getCapabilityConfig(\n capabilityId: string,\n bodyCapability?: CapabilityConfig,\n ): CapabilityConfig {\n if (bodyCapability) {\n return bodyCapability;\n }\n\n const config = this.capabilityService.getCapability(capabilityId);\n if (!config) {\n throw new HttpException(\n {\n code: 1,\n message: `Capability not found: ${capabilityId}`,\n error: 'CAPABILITY_NOT_FOUND',\n },\n HttpStatus.NOT_FOUND,\n );\n }\n\n return config;\n }\n\n /**\n * 获取 action 名称\n * 优先使用传入的 action,否则使用插件第一个 action\n */\n private async getActionName(pluginKey: string, bodyAction?: string): Promise<string> {\n if (bodyAction) {\n return bodyAction;\n }\n\n const pluginInstance = await this.pluginLoaderService.loadPlugin(pluginKey);\n const actions = pluginInstance.listActions();\n\n if (actions.length === 0) {\n throw new HttpException(\n {\n code: 1,\n message: `Plugin ${pluginKey} has no actions`,\n error: 'NO_ACTIONS',\n },\n HttpStatus.BAD_REQUEST,\n );\n }\n\n return actions[0];\n }\n\n @Post('debug/:capability_id')\n async debug(\n @Param('capability_id') capabilityId: string,\n @Body() body: DebugRequestBody,\n ): Promise<SuccessResponse<DebugExecuteResponseData> | ErrorResponse> {\n const startTime = Date.now();\n const params = body.params ?? {};\n\n const config = this.getCapabilityConfig(capabilityId, body.capability);\n const action = await this.getActionName(config.pluginKey, body.action);\n\n const resolvedParams = this.templateEngineService.resolve(\n config.formValue,\n params,\n );\n\n try {\n const result = await this.capabilityService\n .loadWithConfig(config)\n .call(action, params);\n\n return {\n status_code: ErrorCodes.SUCCESS,\n data: {\n output: result,\n debug: {\n capabilityConfig: config,\n resolvedParams,\n duration: Date.now() - startTime,\n pluginID: config.pluginKey,\n action,\n },\n },\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n status_code: ErrorCodes.CAPABILITY_NOT_FOUND,\n error_msg: `Capability not found: ${capabilityId}`,\n } satisfies ErrorResponse,\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n status_code: ErrorCodes.PLUGIN_NOT_FOUND,\n error_msg: `Plugin not found: ${config.pluginKey}`,\n } satisfies ErrorResponse,\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n status_code: ErrorCodes.ACTION_NOT_FOUND,\n error_msg: `Action '${action}' not found in plugin ${config.pluginKey}`,\n } satisfies ErrorResponse,\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n status_code: ErrorCodes.EXECUTION_ERROR,\n error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`,\n } satisfies ErrorResponse,\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n\n @Post('debug/:capability_id/stream')\n async debugStream(\n @Param('capability_id') capabilityId: string,\n @Body() body: DebugRequestBody,\n @Res() res: Response,\n ): Promise<void> {\n const params = body.params ?? {};\n\n // 设置 SSE 响应头\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const config = this.getCapabilityConfig(capabilityId, body.capability);\n const action = await this.getActionName(config.pluginKey, body.action);\n\n const capability = this.capabilityService.loadWithConfig(config);\n const eventStream = capability.callStreamWithEvents(action, params);\n\n // 边收边发:根据事件类型处理\n for await (const event of eventStream) {\n switch (event.type) {\n case 'data': {\n // 数据事件:立即发送给客户端\n const response: StreamContentResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'content',\n delta: { content: event.data },\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n break;\n }\n\n case 'done': {\n // 完成事件:发送 finished 标记\n const response: StreamContentResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'content',\n delta: { content: null },\n finished: true,\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n res.end();\n return;\n }\n\n case 'error': {\n // 错误事件:发送错误信息\n const response: StreamErrorResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'error',\n error: {\n code: 0,\n message: event.error.message,\n },\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n res.end();\n return;\n }\n }\n }\n\n // 如果事件流正常结束但没有 done 事件,确保关闭连接\n res.end();\n } catch (error) {\n // 流异常中断(在事件流开始前的错误)\n const errorMsg = error instanceof Error ? error.message : String(error);\n const response: StreamErrorResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'error',\n error: {\n code: 0,\n message: errorMsg,\n },\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n res.end();\n }\n }\n}\n","import {\n Controller,\n Get,\n Post,\n Param,\n Body,\n Res,\n HttpException,\n HttpStatus,\n} from '@nestjs/common';\nimport type { Response } from 'express';\nimport {\n CapabilityService,\n CapabilityNotFoundError,\n ActionNotFoundError,\n} from '../services/capability.service';\nimport { PluginNotFoundError } from '../services/plugin-loader.service';\nimport type {\n SuccessResponse,\n ErrorResponse,\n ExecuteResponseData,\n ListResponseData,\n StreamContentResponse,\n StreamErrorResponse,\n} from '../interfaces';\nimport { ErrorCodes } from '../interfaces';\n\ninterface ExecuteRequestBody {\n action: string;\n params: Record<string, unknown>;\n}\n\n@Controller('api/capability')\nexport class WebhookController {\n constructor(private readonly capabilityService: CapabilityService) {}\n\n @Get('list')\n list(): SuccessResponse<ListResponseData> {\n const capabilities = this.capabilityService.listCapabilities();\n return {\n status_code: ErrorCodes.SUCCESS,\n data: {\n capabilities: capabilities.map(c => ({\n id: c.id,\n name: c.name,\n pluginID: c.pluginKey,\n pluginVersion: c.pluginVersion,\n })),\n },\n };\n }\n\n @Post(':capability_id')\n async execute(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n ): Promise<SuccessResponse<ExecuteResponseData> | ErrorResponse> {\n try {\n const result = await this.capabilityService\n .load(capabilityId)\n .call(body.action, body.params);\n\n return {\n status_code: ErrorCodes.SUCCESS,\n data: {\n output: result,\n },\n };\n } catch (error) {\n if (error instanceof CapabilityNotFoundError) {\n throw new HttpException(\n {\n status_code: ErrorCodes.CAPABILITY_NOT_FOUND,\n error_msg: `Capability not found: ${capabilityId}`,\n } satisfies ErrorResponse,\n HttpStatus.NOT_FOUND,\n );\n }\n\n if (error instanceof PluginNotFoundError) {\n throw new HttpException(\n {\n status_code: ErrorCodes.PLUGIN_NOT_FOUND,\n error_msg: `Plugin not found`,\n } satisfies ErrorResponse,\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n\n if (error instanceof ActionNotFoundError) {\n throw new HttpException(\n {\n status_code: ErrorCodes.ACTION_NOT_FOUND,\n error_msg: `Action '${body.action}' not found`,\n } satisfies ErrorResponse,\n HttpStatus.BAD_REQUEST,\n );\n }\n\n throw new HttpException(\n {\n status_code: ErrorCodes.EXECUTION_ERROR,\n error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`,\n } satisfies ErrorResponse,\n HttpStatus.INTERNAL_SERVER_ERROR,\n );\n }\n }\n\n @Post(':capability_id/stream')\n async executeStream(\n @Param('capability_id') capabilityId: string,\n @Body() body: ExecuteRequestBody,\n @Res() res: Response,\n ): Promise<void> {\n // 设置 SSE 响应头\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n\n try {\n const capability = this.capabilityService.load(capabilityId);\n const eventStream = capability.callStreamWithEvents(body.action, body.params);\n\n // 边收边发:根据事件类型处理\n for await (const event of eventStream) {\n switch (event.type) {\n case 'data': {\n // 数据事件:立即发送给客户端\n const response: StreamContentResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'content',\n delta: { content: event.data },\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n break;\n }\n\n case 'done': {\n // 完成事件:发送 finished 标记\n const response: StreamContentResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'content',\n delta: { content: null },\n finished: true,\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n res.end();\n return;\n }\n\n case 'error': {\n // 错误事件:发送错误信息\n const response: StreamErrorResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'error',\n error: {\n code: 0,\n message: event.error.message,\n },\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n res.end();\n return;\n }\n }\n }\n\n // 如果事件流正常结束但没有 done 事件,确保关闭连接\n res.end();\n } catch (error) {\n // 流异常中断(在事件流开始前的错误)\n const errorMsg = error instanceof Error ? error.message : String(error);\n const response: StreamErrorResponse = {\n status_code: ErrorCodes.SUCCESS,\n data: {\n type: 'error',\n error: {\n code: 0,\n message: errorMsg,\n },\n },\n };\n res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n res.end();\n }\n }\n}\n","import { Module, DynamicModule, Type } from '@nestjs/common';\nimport {\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n CapabilityService,\n PluginLoaderService,\n TemplateEngineService,\n type CapabilityModuleOptions,\n} from './services';\n\nconst CAPABILITY_OPTIONS = Symbol('CAPABILITY_OPTIONS');\n\nconst isDevelopment = process.env.NODE_ENV === 'development';\n\nfunction getControllers(): Type[] {\n const controllers: Type[] = [WebhookController];\n if (isDevelopment) {\n controllers.push(DebugController);\n }\n return controllers;\n}\n\n@Module({\n controllers: getControllers(),\n providers: [CapabilityService, PluginLoaderService, TemplateEngineService],\n exports: [CapabilityService],\n})\nexport class CapabilityModule {\n static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n return {\n module: CapabilityModule,\n controllers: getControllers(),\n providers: [\n {\n provide: CAPABILITY_OPTIONS,\n useValue: options ?? {},\n },\n {\n provide: CapabilityService,\n useFactory: (\n requestContextService: RequestContextService,\n httpClient: any,\n pluginLoader: PluginLoaderService,\n templateEngine: TemplateEngineService,\n moduleOptions: CapabilityModuleOptions,\n ) => {\n const service = new CapabilityService(\n requestContextService,\n httpClient,\n pluginLoader,\n templateEngine,\n );\n if (moduleOptions?.capabilitiesDir) {\n service.setCapabilitiesDir(moduleOptions.capabilitiesDir);\n }\n return service;\n },\n inject: [\n RequestContextService,\n PLATFORM_HTTP_CLIENT,\n PluginLoaderService,\n TemplateEngineService,\n CAPABILITY_OPTIONS,\n ],\n },\n PluginLoaderService,\n TemplateEngineService,\n ],\n exports: [CapabilityService],\n };\n }\n}\n"],"mappings":"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","names":["ErrorCodes","SUCCESS","CAPABILITY_NOT_FOUND","PLUGIN_NOT_FOUND","ACTION_NOT_FOUND","PARAMS_VALIDATION_ERROR","EXECUTION_ERROR","TemplateEngineService","EXPR_REGEX","WHOLE_STRING_EXPR_REGEX","resolve","template","input","resolveString","Array","isArray","map","item","resolveObject","wholeMatch","match","path","value","getValueByPath","undefined","lastIndex","test","result","replace","String","key","Object","entries","obj","keys","split","current","import_common","PluginNotFoundError","Error","pluginKey","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","loadPlugin","cached","get","debug","log","pluginPackage","default","create","instance","set","error","code","message","String","isPluginInstalled","require","resolve","clearCache","delete","clear","import_common","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginKey","actionName","CapabilityService","logger","Logger","capabilities","Map","capabilitiesDir","requestContextService","httpClient","pluginLoaderService","templateEngineService","join","process","cwd","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","log","existsSync","warn","files","readdirSync","filter","f","endsWith","file","filePath","content","readFileSync","config","JSON","parse","id","set","error","size","listCapabilities","Array","from","values","getCapability","get","load","createExecutor","loadWithConfig","call","input","contextOverride","executeCall","callStream","executeCallStream","callStreamWithEvents","executeCallStreamWithEvents","isStream","checkIsStream","pluginInstance","loadPlugin","hasAction","isStreamAction","startTime","Date","now","resolvedParams","resolve","formValue","context","buildActionContext","message","action","result","runStream","chunks","chunk","push","aggregate","run","duration","String","chunkCount","runStreamWithEvents","type","data","metadata","code","override","userContext","getUserContext","ctx","getContext","userId","tenantId","import_common","DebugController","capabilityService","pluginLoaderService","templateEngineService","list","capabilities","listCapabilities","status_code","ErrorCodes","SUCCESS","data","map","c","id","name","pluginID","pluginKey","pluginVersion","getCapabilityConfig","capabilityId","bodyCapability","config","getCapability","HttpException","code","message","error","HttpStatus","NOT_FOUND","getActionName","bodyAction","pluginInstance","loadPlugin","actions","listActions","length","BAD_REQUEST","debug","body","startTime","Date","now","params","capability","action","resolvedParams","resolve","formValue","result","loadWithConfig","call","output","capabilityConfig","duration","CapabilityNotFoundError","CAPABILITY_NOT_FOUND","error_msg","PluginNotFoundError","PLUGIN_NOT_FOUND","INTERNAL_SERVER_ERROR","ActionNotFoundError","ACTION_NOT_FOUND","EXECUTION_ERROR","Error","String","debugStream","res","setHeader","eventStream","callStreamWithEvents","event","type","response","delta","content","write","JSON","stringify","finished","end","errorMsg","import_common","WebhookController","capabilityService","list","capabilities","listCapabilities","status_code","ErrorCodes","SUCCESS","data","map","c","id","name","pluginID","pluginKey","pluginVersion","execute","capabilityId","body","result","load","call","action","params","output","error","CapabilityNotFoundError","HttpException","CAPABILITY_NOT_FOUND","error_msg","HttpStatus","NOT_FOUND","PluginNotFoundError","PLUGIN_NOT_FOUND","INTERNAL_SERVER_ERROR","ActionNotFoundError","ACTION_NOT_FOUND","BAD_REQUEST","EXECUTION_ERROR","Error","message","String","executeStream","res","setHeader","capability","eventStream","callStreamWithEvents","event","type","response","delta","content","write","JSON","stringify","finished","end","code","errorMsg","import_common","import_nestjs_common","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClient","pluginLoader","templateEngine","moduleOptions","service","capabilitiesDir","setCapabilitiesDir","inject","RequestContextService","PLATFORM_HTTP_CLIENT","PluginLoaderService","TemplateEngineService","exports"]}
package/dist/index.d.cts CHANGED
@@ -13,6 +13,143 @@ interface PluginActionContext {
13
13
  userContext: UserContext;
14
14
  }
15
15
 
16
+ interface JSONSchema {
17
+ type?: string;
18
+ properties?: Record<string, JSONSchema>;
19
+ required?: string[];
20
+ items?: JSONSchema;
21
+ [key: string]: unknown;
22
+ }
23
+ interface CapabilityConfig {
24
+ id: string;
25
+ pluginKey: string;
26
+ pluginVersion: string;
27
+ name: string;
28
+ description: string;
29
+ paramsSchema: JSONSchema;
30
+ formValue: Record<string, unknown>;
31
+ createdAt: number;
32
+ updatedAt: number;
33
+ }
34
+
35
+ /**
36
+ * 成功响应基础结构
37
+ */
38
+ interface SuccessResponse<T> {
39
+ status_code: '0';
40
+ data: T;
41
+ }
42
+ /**
43
+ * 错误响应结构
44
+ */
45
+ interface ErrorResponse {
46
+ status_code: string;
47
+ error_msg: string;
48
+ }
49
+ /**
50
+ * Debug 信息
51
+ */
52
+ interface DebugInfo {
53
+ capabilityConfig: CapabilityConfig;
54
+ resolvedParams: unknown;
55
+ duration: number;
56
+ pluginID: string;
57
+ action: string;
58
+ }
59
+ /**
60
+ * 执行接口响应 data 结构
61
+ */
62
+ interface ExecuteResponseData {
63
+ output: unknown;
64
+ }
65
+ /**
66
+ * Debug 执行接口响应 data 结构
67
+ */
68
+ interface DebugExecuteResponseData {
69
+ output: unknown;
70
+ debug: DebugInfo;
71
+ }
72
+ /**
73
+ * 能力列表项
74
+ */
75
+ interface CapabilityListItem {
76
+ id: string;
77
+ name: string;
78
+ pluginID: string;
79
+ pluginVersion: string;
80
+ }
81
+ /**
82
+ * 列表接口响应 data 结构
83
+ */
84
+ interface ListResponseData {
85
+ capabilities: CapabilityListItem[];
86
+ }
87
+ /**
88
+ * 流式内容响应
89
+ */
90
+ interface StreamContentResponse {
91
+ status_code: '0';
92
+ data: {
93
+ type: 'content';
94
+ delta: {
95
+ content: unknown;
96
+ };
97
+ finished?: boolean;
98
+ };
99
+ }
100
+ /**
101
+ * 流式错误响应
102
+ */
103
+ interface StreamErrorResponse {
104
+ status_code: '0';
105
+ data: {
106
+ type: 'error';
107
+ error: {
108
+ code: number;
109
+ message: string;
110
+ };
111
+ };
112
+ }
113
+ /**
114
+ * 流式响应类型
115
+ */
116
+ type StreamResponse = StreamContentResponse | StreamErrorResponse;
117
+ /**
118
+ * 流完成元数据
119
+ */
120
+ interface StreamDoneMetadata {
121
+ /** chunk 总数 */
122
+ chunks: number;
123
+ /** 流持续时间 (ms) */
124
+ duration: number;
125
+ /** 聚合结果(可选) */
126
+ aggregated?: unknown;
127
+ }
128
+ /**
129
+ * 流错误信息
130
+ */
131
+ interface StreamError {
132
+ code: string;
133
+ message: string;
134
+ details?: unknown;
135
+ }
136
+ /**
137
+ * 流事件类型
138
+ * - data: 数据事件,包含单个 chunk
139
+ * - done: 完成事件,包含元数据
140
+ * - error: 错误事件,包含错误信息
141
+ */
142
+ type StreamEvent<T> = {
143
+ type: 'data';
144
+ data: T;
145
+ } | {
146
+ type: 'done';
147
+ metadata: StreamDoneMetadata;
148
+ } | {
149
+ type: 'error';
150
+ error: StreamError;
151
+ };
152
+
16
153
  interface ActionSchema {
17
154
  input: ZodSchema | ((config: unknown) => ZodSchema);
18
155
  output?: ZodSchema | ((input: unknown, config: unknown) => ZodSchema);
@@ -30,8 +167,10 @@ interface PluginInstance {
30
167
  getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined;
31
168
  /** 列出所有 action */
32
169
  listActions(): string[];
33
- /** 流式执行指定 action */
170
+ /** 流式执行指定 action,返回原始流 */
34
171
  runStream?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<unknown>;
172
+ /** 流式执行指定 action,返回带事件协议的流(推荐) */
173
+ runStreamWithEvents?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<StreamEvent<unknown>>;
35
174
  /** 检查 action 是否为流式 */
36
175
  isStreamAction?(actionName: string): boolean;
37
176
  /** 聚合流式结果(可选,插件自定义聚合逻辑) */
@@ -41,24 +180,24 @@ interface PluginPackage {
41
180
  create(): PluginInstance;
42
181
  }
43
182
 
44
- interface JSONSchema {
45
- type?: string;
46
- properties?: Record<string, JSONSchema>;
47
- required?: string[];
48
- items?: JSONSchema;
49
- [key: string]: unknown;
50
- }
51
- interface CapabilityConfig {
52
- id: string;
53
- pluginID: string;
54
- pluginVersion: string;
55
- name: string;
56
- description: string;
57
- paramsSchema: JSONSchema;
58
- formValue: Record<string, unknown>;
59
- createdAt: number;
60
- updatedAt: number;
61
- }
183
+ /**
184
+ * Capability 模块错误码
185
+ */
186
+ declare const ErrorCodes: {
187
+ /** 成功 */
188
+ readonly SUCCESS: "0";
189
+ /** 能力不存在 */
190
+ readonly CAPABILITY_NOT_FOUND: "k_ec_cap_001";
191
+ /** 插件不存在 */
192
+ readonly PLUGIN_NOT_FOUND: "k_ec_cap_002";
193
+ /** Action 不存在 */
194
+ readonly ACTION_NOT_FOUND: "k_ec_cap_003";
195
+ /** 参数验证失败 */
196
+ readonly PARAMS_VALIDATION_ERROR: "k_ec_cap_004";
197
+ /** 执行失败 */
198
+ readonly EXECUTION_ERROR: "k_ec_cap_005";
199
+ };
200
+ type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
62
201
 
63
202
  /**
64
203
  * 模板引擎服务
@@ -88,24 +227,24 @@ declare class TemplateEngineService {
88
227
  }
89
228
 
90
229
  declare class PluginNotFoundError extends Error {
91
- constructor(pluginID: string);
230
+ constructor(pluginKey: string);
92
231
  }
93
232
  declare class PluginLoadError extends Error {
94
- constructor(pluginID: string, reason: string);
233
+ constructor(pluginKey: string, reason: string);
95
234
  }
96
235
  declare class PluginLoaderService {
97
236
  private readonly logger;
98
237
  private readonly pluginInstances;
99
- loadPlugin(pluginID: string): Promise<PluginInstance>;
100
- isPluginInstalled(pluginID: string): boolean;
101
- clearCache(pluginID?: string): void;
238
+ loadPlugin(pluginKey: string): Promise<PluginInstance>;
239
+ isPluginInstalled(pluginKey: string): boolean;
240
+ clearCache(pluginKey?: string): void;
102
241
  }
103
242
 
104
243
  declare class CapabilityNotFoundError extends Error {
105
244
  constructor(capabilityId: string);
106
245
  }
107
246
  declare class ActionNotFoundError extends Error {
108
- constructor(pluginID: string, actionName: string);
247
+ constructor(pluginKey: string, actionName: string);
109
248
  }
110
249
  interface CapabilityExecutor {
111
250
  /**
@@ -115,11 +254,18 @@ interface CapabilityExecutor {
115
254
  */
116
255
  call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;
117
256
  /**
118
- * 流式调用 capability
257
+ * 流式调用 capability,返回原始流
119
258
  * - 返回原始 AsyncIterable
120
259
  * - 如果 action 是 unary,包装为单次 yield
121
260
  */
122
261
  callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;
262
+ /**
263
+ * 流式调用 capability,返回带事件协议的流(推荐)
264
+ * - 返回 StreamEvent 类型的 AsyncIterable
265
+ * - 支持 data/done/error 三种事件类型
266
+ * - Controller 层应优先使用此方法实现边收边发
267
+ */
268
+ callStreamWithEvents(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<StreamEvent<unknown>>;
123
269
  /**
124
270
  * 检查 action 是否为流式
125
271
  */
@@ -165,6 +311,12 @@ declare class CapabilityService implements OnModuleInit {
165
311
  * - unary action: 包装为单次 yield
166
312
  */
167
313
  private executeCallStream;
314
+ /**
315
+ * 流式执行 capability,返回带事件协议的流
316
+ * - 优先使用 pluginInstance.runStreamWithEvents
317
+ * - 如果插件不支持,则包装 runStream/run 为 StreamEvent
318
+ */
319
+ private executeCallStreamWithEvents;
168
320
  private buildActionContext;
169
321
  private getUserContext;
170
322
  }
@@ -174,34 +326,12 @@ interface DebugRequestBody {
174
326
  params?: Record<string, unknown>;
175
327
  capability?: CapabilityConfig;
176
328
  }
177
- interface DebugResponse {
178
- code: number;
179
- message: string;
180
- data: unknown;
181
- debug?: {
182
- capabilityConfig: unknown;
183
- resolvedParams: unknown;
184
- duration: number;
185
- pluginID: string;
186
- action: string;
187
- };
188
- }
189
- interface ListResponse$1 {
190
- code: number;
191
- message: string;
192
- data: Array<{
193
- id: string;
194
- name: string;
195
- pluginID: string;
196
- pluginVersion: string;
197
- }>;
198
- }
199
329
  declare class DebugController {
200
330
  private readonly capabilityService;
201
331
  private readonly pluginLoaderService;
202
332
  private readonly templateEngineService;
203
333
  constructor(capabilityService: CapabilityService, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService);
204
- list(): ListResponse$1;
334
+ list(): SuccessResponse<ListResponseData>;
205
335
  /**
206
336
  * 获取 capability 配置
207
337
  * 优先使用 body.capability,否则从服务获取
@@ -212,7 +342,7 @@ declare class DebugController {
212
342
  * 优先使用传入的 action,否则使用插件第一个 action
213
343
  */
214
344
  private getActionName;
215
- debug(capabilityId: string, body: DebugRequestBody): Promise<DebugResponse>;
345
+ debug(capabilityId: string, body: DebugRequestBody): Promise<SuccessResponse<DebugExecuteResponseData> | ErrorResponse>;
216
346
  debugStream(capabilityId: string, body: DebugRequestBody, res: Response): Promise<void>;
217
347
  }
218
348
 
@@ -220,28 +350,11 @@ interface ExecuteRequestBody {
220
350
  action: string;
221
351
  params: Record<string, unknown>;
222
352
  }
223
- interface ExecuteResponse {
224
- code: number;
225
- message: string;
226
- data: unknown;
227
- }
228
- interface CapabilityInfo {
229
- id: string;
230
- name: string;
231
- description: string;
232
- pluginID: string;
233
- pluginVersion: string;
234
- }
235
- interface ListResponse {
236
- code: number;
237
- message: string;
238
- data: CapabilityInfo[];
239
- }
240
353
  declare class WebhookController {
241
354
  private readonly capabilityService;
242
355
  constructor(capabilityService: CapabilityService);
243
- list(): ListResponse;
244
- execute(capabilityId: string, body: ExecuteRequestBody): Promise<ExecuteResponse>;
356
+ list(): SuccessResponse<ListResponseData>;
357
+ execute(capabilityId: string, body: ExecuteRequestBody): Promise<SuccessResponse<ExecuteResponseData> | ErrorResponse>;
245
358
  executeStream(capabilityId: string, body: ExecuteRequestBody, res: Response): Promise<void>;
246
359
  }
247
360
 
@@ -249,4 +362,4 @@ declare class CapabilityModule {
249
362
  static forRoot(options?: CapabilityModuleOptions): DynamicModule;
250
363
  }
251
364
 
252
- export { ActionNotFoundError, type ActionSchema, type CapabilityConfig, type CapabilityExecutor, CapabilityModule, type CapabilityModuleOptions, CapabilityNotFoundError, CapabilityService, DebugController, type JSONSchema, type PluginActionContext, type PluginInstance, PluginLoadError, PluginLoaderService, PluginNotFoundError, type PluginPackage, TemplateEngineService, type UserContext, WebhookController };
365
+ export { ActionNotFoundError, type ActionSchema, type CapabilityConfig, type CapabilityExecutor, type CapabilityListItem, CapabilityModule, type CapabilityModuleOptions, CapabilityNotFoundError, CapabilityService, DebugController, type DebugExecuteResponseData, type DebugInfo, type ErrorCode, ErrorCodes, type ErrorResponse, type ExecuteResponseData, type JSONSchema, type ListResponseData, type PluginActionContext, type PluginInstance, PluginLoadError, PluginLoaderService, PluginNotFoundError, type PluginPackage, type StreamContentResponse, type StreamDoneMetadata, type StreamError, type StreamErrorResponse, type StreamEvent, type StreamResponse, type SuccessResponse, TemplateEngineService, type UserContext, WebhookController };