{"version":3,"sources":["../src/index.ts","../../../../node_modules/tsup/assets/cjs_shims.js","../src/interfaces/error-codes.ts","../src/services/template-engine.service.ts","../src/services/plugin-loader.service.ts","../src/services/capability.service.ts","../src/services/telemetry.service.ts","../src/utils/log-utils.ts","../src/utils/migration-adaptor.ts","../src/utils/plugin-error-format.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';\nexport { migrationAdaptor, type MigrationResponse, type FailureOutput } from './utils/migration-adaptor';\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n  typeof document === \"undefined\" \n    ? new URL(`file:${__filename}`).href \n    : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n      ? document.currentScript.src \n      : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\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  /** 计费受限 */\n  RATE_LIMIT_EXCEEDED: 'k_ec_cap_006',\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n","import { Injectable } from '@nestjs/common';\nimport { JSONSchema } from '../interfaces/capability-config.interface';\n\n/**\n * 类型到默认值的映射\n */\nconst TYPE_DEFAULT_VALUES: Record<string, unknown> = {\n  array: [],\n  object: {},\n  string: '',\n  number: 0,\n  integer: 0,\n  boolean: false,\n  null: null,\n};\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 *   - 未传 schema：返回原始表达式\n *   - 传了 schema（整串表达式）：按 schema 返回默认值\n *   - 传了 schema（字符串插值）：保留原始表达式\n */\n@Injectable()\nexport class TemplateEngineService {\n  // 匹配 {{input.xxx}} 或 {{input.xxx.yyy}} 表达式\n  private readonly EXPR_REGEX =\n    /\\{\\{\\s*input\\.([a-zA-Z_][a-zA-Z_0-9]*(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)*\\s*)\\}\\}/g;\n  // 匹配整串单个表达式\n  private readonly WHOLE_STRING_EXPR_REGEX =\n    /^\\{\\{\\s*input\\.([a-zA-Z_][a-zA-Z_0-9]*(?:\\.[a-zA-Z_][a-zA-Z_0-9]*)*)\\s*\\}\\}$/;\n\n  /**\n   * 解析 formValue 模板\n   * @param template - formValue 模板对象\n   * @param input - 用户输入参数\n   * @param paramsSchema - 可选，输入参数的 JSON Schema，用于推断默认值\n   * @returns 解析后的参数对象\n   */\n  resolve(\n    template: unknown,\n    input: Record<string, unknown>,\n    paramsSchema?: JSONSchema,\n  ): unknown {\n    if (typeof template === 'string') {\n      return this.resolveString(template, input, paramsSchema);\n    }\n\n    if (Array.isArray(template)) {\n      return template.map(item => this.resolve(item, input, paramsSchema));\n    }\n\n    if (template !== null && typeof template === 'object') {\n      return this.resolveObject(\n        template as Record<string, unknown>,\n        input,\n        paramsSchema,\n      );\n    }\n\n    return template;\n  }\n\n  private resolveString(\n    template: string,\n    input: Record<string, unknown>,\n    paramsSchema?: JSONSchema,\n  ): 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      // 变量存在，返回值\n      if (value !== undefined) {\n        return value;\n      }\n\n      // 变量不存在，尝试从 schema 获取默认值\n      if (paramsSchema) {\n        const defaultValue = this.getDefaultValueForPath(path, paramsSchema);\n        if (defaultValue !== undefined) {\n          return defaultValue;\n        }\n      }\n\n      // 回退：返回原始表达式\n      return template;\n    }\n\n    // 情况2: 字符串插值 → 返回字符串（不使用 schema 默认值）\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    paramsSchema?: JSONSchema,\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, paramsSchema);\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  /**\n   * 根据路径从 schema 获取默认值\n   * @param path - 变量路径，如 \"a.b.c\"\n   * @param schema - JSON Schema\n   * @returns 默认值，如果无法确定则返回 undefined\n   */\n  private getDefaultValueForPath(\n    path: string,\n    schema: JSONSchema,\n  ): unknown {\n    const fieldSchema = this.getSchemaForPath(path, schema);\n    if (!fieldSchema) {\n      return undefined;\n    }\n    return this.getDefaultValueFromSchema(fieldSchema);\n  }\n\n  /**\n   * 根据路径查找对应的 schema 定义\n   * @param path - 变量路径，如 \"a.b.c\"\n   * @param schema - 根 JSON Schema\n   * @returns 路径对应的 schema，如果不存在则返回 undefined\n   */\n  private getSchemaForPath(\n    path: string,\n    schema: JSONSchema,\n  ): JSONSchema | undefined {\n    const keys = path.split('.');\n    let currentSchema: JSONSchema | undefined = schema;\n\n    for (const key of keys) {\n      if (!currentSchema?.properties) {\n        return undefined;\n      }\n      currentSchema = currentSchema.properties[key];\n      if (!currentSchema) {\n        return undefined;\n      }\n    }\n\n    return currentSchema;\n  }\n\n  /**\n   * 从 schema 获取默认值\n   * 优先级：default > type > undefined\n   * @param schema - 字段的 JSON Schema\n   * @returns 默认值\n   */\n  private getDefaultValueFromSchema(schema: JSONSchema): unknown {\n    // 优先使用 schema 中定义的 default\n    if (schema.default !== undefined) {\n      return schema.default;\n    }\n\n    // 如果有 oneOf 或 anyOf，无法确定类型，返回 undefined\n    if (schema.oneOf || schema.anyOf) {\n      return undefined;\n    }\n\n    // 根据 type 返回默认值\n    const type = schema.type;\n    if (!type) {\n      return undefined;\n    }\n\n    // 联合类型：取第一个类型的默认值\n    if (Array.isArray(type)) {\n      for (const t of type) {\n        if (t in TYPE_DEFAULT_VALUES) {\n          return TYPE_DEFAULT_VALUES[t];\n        }\n      }\n      return undefined;\n    }\n\n    // 单一类型\n    return TYPE_DEFAULT_VALUES[type];\n  }\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport { createRequire } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { PluginInstance, PluginPackage } from '../interfaces';\n\nexport interface PluginManifest {\n  name: string;\n  version?: string;\n  displayName?: string;\n  form?: {\n    refType?: 'config' | 'action';\n    schema?: unknown;\n  };\n  [key: string]: unknown;\n}\n\n// 社区标准模式：tsup shims 会为 CJS 输出自动处理 import.meta.url\nconst require = createRequire(import.meta.url);\n\nexport class PluginNotFoundError extends Error {\n  readonly pluginKey: string;\n\n  constructor(pluginKey: string) {\n    super(`Plugin not found: ${pluginKey}`);\n    this.name = 'PluginNotFoundError';\n    this.pluginKey = pluginKey;\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  /** 记录每个插件的加载版本（时间戳），用于 ESM 缓存绕过 */\n  private readonly pluginVersions = new Map<string, number>();\n  /** 缓存插件的 manifest.json */\n  private readonly manifestCache = new Map<string, PluginManifest | null>();\n\n  /**\n   * 从入口路径向上查找包根目录（包含 package.json 的目录）\n   */\n  private findPackageRoot(entryPath: string): string | null {\n    let dir = path.dirname(entryPath);\n    while (dir !== path.dirname(dir)) {\n      // 未到达根目录\n      if (fs.existsSync(path.join(dir, 'package.json'))) {\n        return dir;\n      }\n      dir = path.dirname(dir);\n    }\n    return null;\n  }\n\n  /**\n   * 读取并缓存 manifest\n   */\n  getManifest(pluginKey: string): PluginManifest | null {\n    // 检查缓存\n    if (this.manifestCache.has(pluginKey)) {\n      return this.manifestCache.get(pluginKey) ?? null;\n    }\n\n    try {\n      // 1. 获取插件入口路径\n      const entryPath = require.resolve(pluginKey);\n\n      // 2. 从入口路径反推包根目录\n      const packageRoot = this.findPackageRoot(entryPath);\n      if (!packageRoot) {\n        this.manifestCache.set(pluginKey, null);\n        return null;\n      }\n\n      // 3. 读取 manifest.json\n      const manifestPath = path.join(packageRoot, 'manifest.json');\n      if (!fs.existsSync(manifestPath)) {\n        this.manifestCache.set(pluginKey, null);\n        return null;\n      }\n\n      const content = fs.readFileSync(manifestPath, 'utf-8');\n      const manifest = JSON.parse(content) as PluginManifest;\n      this.manifestCache.set(pluginKey, manifest);\n      return manifest;\n    } catch {\n      // 读取失败时缓存 null，避免重复尝试\n      this.manifestCache.set(pluginKey, null);\n      return null;\n    }\n  }\n\n  /**\n   * 检查插件是否需要 config（form.refType === 'config'）\n   */\n  isConfigRequired(pluginKey: string): boolean {\n    const manifest = this.getManifest(pluginKey);\n    return manifest?.form?.refType === 'config';\n  }\n\n  async loadPlugin(pluginKey: string, config?: unknown): Promise<PluginInstance> {\n    const isConfigRequired = this.isConfigRequired(pluginKey);\n\n    // refType: \"config\" 的插件不缓存，每次重新创建\n    if (isConfigRequired) {\n      return this.createPluginInstance(pluginKey, config);\n    }\n\n    // refType: \"action\" 的插件使用缓存\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    const instance = await this.createPluginInstance(pluginKey);\n    this.pluginInstances.set(pluginKey, instance);\n    return instance;\n  }\n\n  /**\n   * 创建插件实例（内部方法）\n   */\n  private async createPluginInstance(pluginKey: string, config?: unknown): Promise<PluginInstance> {\n    this.logger.log(`Loading plugin: ${pluginKey}${config !== undefined ? ' (with config)' : ''}`);\n\n    try {\n      // 1. 将包名解析为实际文件路径\n      const resolvedPath = require.resolve(pluginKey);\n\n      // 2. 使用 file:// URL + 时间戳绕过 ESM 缓存\n      const version = this.pluginVersions.get(pluginKey) ?? 0;\n      const fileUrl = pathToFileURL(resolvedPath).href;\n      const importPath = version > 0 ? `${fileUrl}?v=${version}` : fileUrl;\n\n      // 3. 动态导入（支持 ESM 和 CJS 插件）\n      const mod = await import(importPath);\n      const pluginPackage = (mod.default ?? mod) 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(config);\n\n      this.logger.log(`Plugin loaded successfully: ${pluginKey}`);\n\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  /**\n   * 清除插件缓存\n   * - 清除应用层 pluginInstances 缓存\n   * - 清除 manifest 缓存\n   * - 清除 Node.js CJS 模块缓存（require.cache）\n   * - 更新版本号，下次 import 时绕过 ESM 缓存\n   * @param pluginKey - 插件标识，不传则清除所有\n   */\n  clearCache(pluginKey?: string): void {\n    if (pluginKey) {\n      this.pluginInstances.delete(pluginKey);\n      this.manifestCache.delete(pluginKey);\n      this.clearNodeModuleCache(pluginKey);\n      // 更新版本号，下次 import 时使用新的 URL 绕过 ESM 缓存\n      this.pluginVersions.set(pluginKey, Date.now());\n      this.logger.log(`Cleared cache for plugin: ${pluginKey}`);\n    } else {\n      // 清除所有插件\n      for (const key of this.pluginInstances.keys()) {\n        this.clearNodeModuleCache(key);\n        this.pluginVersions.set(key, Date.now());\n      }\n      this.pluginInstances.clear();\n      this.manifestCache.clear();\n      this.logger.log('Cleared all plugin caches');\n    }\n  }\n\n  /**\n   * 清除 CJS 模块缓存\n   */\n  private clearNodeModuleCache(pluginKey: string): void {\n    try {\n      const resolvedPath = require.resolve(pluginKey);\n\n      // 清除主模块及其依赖\n      const mod = require.cache[resolvedPath];\n      if (mod) {\n        this.clearModuleAndChildren(mod, pluginKey);\n      }\n\n      delete require.cache[resolvedPath];\n    } catch {\n      // 插件可能未安装或是纯 ESM 模块，忽略错误\n    }\n  }\n\n  /**\n   * 递归清除子模块缓存\n   */\n  private clearModuleAndChildren(mod: NodeModule, pluginKey: string): void {\n    // 只清除插件目录下的模块，避免清除核心模块\n    const pluginScope = pluginKey.startsWith('@') ? pluginKey.split('/').slice(0, 2).join('/') : pluginKey;\n\n    mod.children.forEach(child => {\n      if (child.filename.includes(`node_modules/${pluginScope}`)) {\n        this.clearModuleAndChildren(child, pluginKey);\n        delete require.cache[child.filename];\n      }\n    });\n  }\n\n  /**\n   * 强制重新加载插件\n   * @param pluginKey - 插件标识\n   */\n  async reloadPlugin(pluginKey: string): Promise<PluginInstance> {\n    this.clearCache(pluginKey);\n    return this.loadPlugin(pluginKey);\n  }\n}\n","import { Injectable, Logger, Inject, OnModuleInit, OnModuleDestroy } from '@nestjs/common';\nimport {\n  RequestContextService,\n  HTTP_CLIENT_FACTORY,\n  type PlatformHttpClient,\n  type HttpClientFactory,\n  type HttpClientWithInterceptors,\n} from '@lark-apaas/nestjs-common';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as chokidar from 'chokidar';\nimport type {\n  CapabilityConfig,\n  JSONSchema,\n  PluginActionContext,\n  PluginInstance,\n  UserContext,\n  StreamEvent,\n} from '../interfaces';\nimport { PluginLoaderService } from './plugin-loader.service';\nimport { TemplateEngineService } from './template-engine.service';\nimport { TelemetryService, type CallerType } from './telemetry.service';\nimport { stringifyForLog } from '../utils';\nimport { formatPluginError } from '../utils/plugin-error-format';\n\nexport class CapabilityNotFoundError extends Error {\n  readonly capabilityId: string;\n\n  constructor(capabilityId: string) {\n    super(`Capability not found: ${capabilityId}`);\n    this.name = 'CapabilityNotFoundError';\n    this.capabilityId = capabilityId;\n  }\n}\n\nexport class ActionNotFoundError extends Error {\n  readonly pluginKey: string;\n  readonly actionName: string;\n\n  constructor(pluginKey: string, actionName: string) {\n    super(`Action '${actionName}' not found in plugin ${pluginKey}`);\n    this.name = 'ActionNotFoundError';\n    this.pluginKey = pluginKey;\n    this.actionName = actionName;\n  }\n}\n\nexport interface ParamDiagnostic {\n  field: string;\n  reason: 'not_provided' | 'empty_value';\n  detail: string;\n}\n\nexport class RequiredParamMissingError extends Error {\n  readonly capabilityName: string;\n  readonly diagnostics: ParamDiagnostic[];\n\n  constructor(capabilityName: string, diagnostics: ParamDiagnostic[]) {\n    const lines = diagnostics.map(d => `  - ${d.field}: ${d.detail}`).join('\\n');\n    super(\n      `「${capabilityName}」插件调用失败，以下必填参数无效:\\n${lines}\\n` +\n      '请检查调用代码中 capabilityClient.load(id).call(action, input) 的 input 对象，' +\n      '确认上述参数已正确传值且未在传递链路中丢失。',\n    );\n    this.name = 'RequiredParamMissingError';\n    this.capabilityName = capabilityName;\n    this.diagnostics = diagnostics;\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  /** 能力配置目录路径，默认 server/capabilities */\n  capabilitiesDir?: string;\n  /** 是否启用文件监听（热更新），默认 false */\n  enableWatching?: boolean;\n  /** 文件变更防抖时间（ms），默认 300 */\n  watchDebounce?: number;\n}\n\n@Injectable()\nexport class CapabilityService implements OnModuleInit, OnModuleDestroy {\n  private readonly logger = new Logger(CapabilityService.name);\n  private readonly capabilities = new Map<string, CapabilityConfig>();\n  /** 文件路径到 capability id 的映射，用于文件删除时查找 */\n  private readonly filePathToId = new Map<string, string>();\n  private capabilitiesDir: string;\n  private fileWatcher: chokidar.FSWatcher | null = null;\n  private options: CapabilityModuleOptions = {};\n\n  constructor(\n    private readonly requestContextService: RequestContextService,\n    @Inject(HTTP_CLIENT_FACTORY) private readonly httpClientFactory: HttpClientFactory,\n    private readonly pluginLoaderService: PluginLoaderService,\n    private readonly templateEngineService: TemplateEngineService,\n    private readonly telemetryService: TelemetryService,\n  ) {\n    this.capabilitiesDir = path.join(process.cwd(), 'server/capabilities');\n  }\n\n  /**\n   * 设置模块配置\n   */\n  setOptions(options: CapabilityModuleOptions): void {\n    this.options = options;\n    if (options.capabilitiesDir) {\n      this.capabilitiesDir = options.capabilitiesDir;\n    }\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    if (this.options.enableWatching) {\n      this.startWatching();\n    }\n  }\n\n  async onModuleDestroy(): Promise<void> {\n    this.stopWatching();\n  }\n\n  // ==================== 文件监听相关方法 ====================\n\n  /**\n   * 启动文件监听（沙箱环境自动调用）\n   */\n  startWatching(): void {\n    if (this.fileWatcher) {\n      return; // 已在监听\n    }\n\n    if (!fs.existsSync(this.capabilitiesDir)) {\n      this.logger.warn(`Cannot start watching: directory not found: ${this.capabilitiesDir}`);\n      return;\n    }\n\n    const pattern = path.join(this.capabilitiesDir, '*.json');\n    const debounce = this.options.watchDebounce ?? 300;\n\n    this.logger.log(`Starting file watcher: ${pattern}`);\n\n    this.fileWatcher = chokidar.watch(pattern, {\n      persistent: true,\n      ignoreInitial: true, // 忽略初始扫描\n      awaitWriteFinish: {\n        // 等待写入完成\n        stabilityThreshold: debounce,\n        pollInterval: 100,\n      },\n    });\n\n    this.fileWatcher\n      .on('add', filePath => this.handleFileAdd(filePath))\n      .on('change', filePath => this.handleFileChange(filePath))\n      .on('unlink', filePath => this.handleFileUnlink(filePath))\n      .on('error', error => this.logger.error('File watcher error:', error));\n\n    this.logger.log('File watcher started');\n  }\n\n  /**\n   * 停止文件监听\n   */\n  stopWatching(): void {\n    if (this.fileWatcher) {\n      this.fileWatcher.close();\n      this.fileWatcher = null;\n      this.logger.log('File watcher stopped');\n    }\n  }\n\n  /**\n   * 重新加载所有能力配置\n   */\n  async reloadAllCapabilities(): Promise<void> {\n    this.capabilities.clear();\n    this.filePathToId.clear();\n    await this.loadCapabilities();\n  }\n\n  private handleFileAdd(filePath: string): void {\n    this.logger.log(`Capability file added: ${filePath}`);\n    try {\n      this.loadCapabilityFromFile(filePath);\n\n      // 清除关联插件的缓存，确保加载最新版本\n      const capabilityId = this.filePathToId.get(filePath);\n      if (capabilityId) {\n        const config = this.capabilities.get(capabilityId);\n        if (config?.pluginKey) {\n          this.pluginLoaderService.clearCache(config.pluginKey);\n          this.logger.log(`Cleared plugin cache for new capability: ${config.pluginKey}`);\n        }\n      }\n    } catch (error) {\n      this.logger.error(`Failed to load new capability: ${filePath}`, error);\n    }\n  }\n\n  private handleFileChange(filePath: string): void {\n    this.logger.log(`Capability file changed: ${filePath}`);\n    try {\n      this.reloadCapabilityFromFile(filePath);\n    } catch (error) {\n      this.logger.error(`Failed to reload capability: ${filePath}`, error);\n    }\n  }\n\n  private handleFileUnlink(filePath: string): void {\n    this.logger.log(`Capability file removed: ${filePath}`);\n    this.removeCapabilityByFile(filePath);\n  }\n\n  /**\n   * 从文件加载单个能力配置\n   */\n  private loadCapabilityFromFile(filePath: string): void {\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: ${filePath}`);\n      return;\n    }\n\n    this.capabilities.set(config.id, config);\n    this.filePathToId.set(filePath, config.id);\n    this.logger.log(`Loaded capability: ${config.id} (${config.name})`);\n  }\n\n  /**\n   * 重新加载单个能力配置\n   */\n  private reloadCapabilityFromFile(filePath: string): void {\n    // 先移除旧配置（如果存在）\n    const oldId = this.filePathToId.get(filePath);\n    if (oldId) {\n      const oldConfig = this.capabilities.get(oldId);\n      if (oldConfig) {\n        // 清除关联插件的缓存\n        this.pluginLoaderService.clearCache(oldConfig.pluginKey);\n      }\n      this.capabilities.delete(oldId);\n    }\n\n    // 重新加载\n    this.loadCapabilityFromFile(filePath);\n  }\n\n  /**\n   * 根据文件路径移除能力配置\n   */\n  private removeCapabilityByFile(filePath: string): void {\n    const capabilityId = this.filePathToId.get(filePath);\n    if (capabilityId) {\n      this.capabilities.delete(capabilityId);\n      this.filePathToId.delete(filePath);\n      this.logger.log(`Removed capability: ${capabilityId}`);\n    }\n  }\n\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        this.loadCapabilityFromFile(filePath);\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   * 加载插件实例并解析参数\n   * 根据 manifest 的 form.refType 决定 formValue 的消费方式\n   */\n  private async loadPluginAndResolveParams(\n    config: CapabilityConfig,\n    input: unknown,\n  ): Promise<{ pluginInstance: PluginInstance; resolvedParams: unknown }> {\n    const isConfigRequired = this.pluginLoaderService.isConfigRequired(config.pluginKey);\n\n    if (isConfigRequired) {\n      // refType: \"config\" - formValue 作为 config 传给 create()\n      const pluginInstance = await this.pluginLoaderService.loadPlugin(\n        config.pluginKey,\n        config.formValue,\n      );\n      // 直接使用 input 作为 action 参数（不经过模板引擎）\n      return { pluginInstance, resolvedParams: input };\n    }\n\n    // refType: \"action\" 或默认 - 保持现有行为\n    const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);\n    const resolvedParams = config.formValue\n      ? this.templateEngineService.resolve(config.formValue, input as Record<string, unknown>, config.paramsSchema)\n      : input;\n    return { pluginInstance, resolvedParams };\n  }\n\n  /**\n   * 校验调用方传入的 input 是否满足 paramsSchema.required 约束。\n   *\n   * 注意：校验发生在模板替换之前。paramsSchema.required 声明的是调用方需要传哪些变量\n   * （它们会被 formValue 中的 {{input.xxx}} 引用），不是 resolve 后的 formValue key。\n   *\n   * Debug 调用（isDebug=true）跳过校验：开发者可能在 paramSchema 里声明了字段但表单\n   * 里并未通过 {{input.xxx}} 实际引用，此时 required 校验会误报；debug 阶段交由\n   * 插件自身的 zod schema 兜底即可。\n   *\n   * 诊断原因：\n   *   not_provided — input 中完全没有该字段（key 不存在 / undefined / null），调用方未传\n   *   empty_value  — 调用方传了值但为空（空串/空数组），需要检查数据来源\n   */\n  private validateRequiredParams(\n    input: unknown,\n    paramsSchema: JSONSchema | undefined,\n    capabilityName: string,\n    isDebug: boolean,\n  ): void {\n    if (isDebug) return;\n    if (!paramsSchema?.required?.length || !paramsSchema.properties) {\n      return;\n    }\n    if (typeof input !== 'object' || input === null) {\n      return;\n    }\n\n    const params = input as Record<string, unknown>;\n    const diagnostics: ParamDiagnostic[] = [];\n\n    for (const fieldName of paramsSchema.required) {\n      const fieldSchema = paramsSchema.properties[fieldName];\n      if (!fieldSchema) continue;\n\n      const value = params[fieldName];\n      const schemaType = fieldSchema.type;\n      const desc = (fieldSchema.description as string) || fieldName;\n\n      // 1. 完全没传（undefined / null）\n      if (value === undefined || value === null) {\n        diagnostics.push({\n          field: fieldName,\n          reason: 'not_provided',\n          detail:\n            `「${desc}」未传值，调用方的 input 中缺少「${fieldName}」字段。` +\n            '请检查 capabilityClient.load(id).call(action, { ... }) 中是否传入了该参数，' +\n            '以及数据在组件传递链路中是否丢失（如 state 未更新、props 未透传等）。',\n        });\n        continue;\n      }\n\n      // 2. 传了但为空值\n      if (schemaType === 'array') {\n        if (Array.isArray(value) && value.length === 0) {\n          diagnostics.push({\n            field: fieldName,\n            reason: 'empty_value',\n            detail:\n              `「${desc}」传入了空数组 []，该字段为必填。` +\n              '请确认数据来源是否正确，例如：列表接口是否返回了数据、文件/图片是否已成功上传。',\n          });\n        }\n      } else if (typeof value === 'string' && value === '') {\n        diagnostics.push({\n          field: fieldName,\n          reason: 'empty_value',\n          detail:\n            `「${desc}」传入了空字符串，该字段为必填。` +\n            '请确认数据来源是否正确，例如：表单字段是否已填写、变量是否已赋值。',\n        });\n      }\n    }\n\n    if (diagnostics.length > 0) {\n      throw new RequiredParamMissingError(capabilityName, diagnostics);\n    }\n  }\n\n  /**\n   * 检查 action 是否为流式\n   */\n  private async checkIsStream(config: CapabilityConfig, actionName: string): Promise<boolean> {\n    const { pluginInstance } = await this.loadPluginAndResolveParams(config, {});\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    const loggerContext = {\n      capability_id: config.id,\n      plugin_key: config.pluginKey,\n      action: actionName,\n    };\n    let isStream = false;\n    try {\n      this.validateRequiredParams(input, config.paramsSchema, config.name, contextOverride?.isDebug ?? false);\n      const { pluginInstance, resolvedParams } = await this.loadPluginAndResolveParams(config, input);\n\n      if (!pluginInstance.hasAction(actionName)) {\n        throw new ActionNotFoundError(config.pluginKey, actionName);\n      }\n\n      const context = this.buildActionContext(config.pluginKey, contextOverride);\n      isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n      // 打印入参\n      this.logger.log('Executing capability (call)', {\n        ...loggerContext,\n        is_stream: isStream,\n        input: stringifyForLog(input),\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      const durationMs = Date.now() - startTime;\n\n      // 打印返回值\n      this.logger.log('Capability (call) executed successfully', {\n        ...loggerContext,\n        duration_ms: durationMs,\n        output: stringifyForLog(result),\n      });\n\n      this.reportCallEvent(config.pluginKey, true, durationMs, isStream, contextOverride);\n\n      return result;\n    } catch (error) {\n      const durationMs = Date.now() - startTime;\n\n      this.logger.error('Capability (call) execution failed', {\n        ...loggerContext,\n        duration_ms: durationMs,\n        error: error instanceof Error ? error.message : String(error),\n      });\n\n      const errorCode = String((error as any)?.code ?? 'EXECUTION_ERROR');\n      this.reportCallEvent(config.pluginKey, false, durationMs, isStream, contextOverride, errorCode);\n\n      // 将 PluginError 的 message 格式化为中文，controller 的 buildErrorResponse 会直接使用\n      const displayName = this.pluginLoaderService.getManifest(config.pluginKey)?.displayName;\n      const formattedMessage = formatPluginError(error, displayName);\n      if (formattedMessage && error instanceof Error) {\n        error.message = formattedMessage;\n      }\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    const loggerContext = {\n      capability_id: config.id,\n      plugin_key: config.pluginKey,\n      action: actionName,\n    };\n    const chunks: unknown[] = [];\n    try {\n      this.validateRequiredParams(input, config.paramsSchema, config.name, contextOverride?.isDebug ?? false);\n      const { pluginInstance, resolvedParams } = await this.loadPluginAndResolveParams(config, input);\n\n      if (!pluginInstance.hasAction(actionName)) {\n        throw new ActionNotFoundError(config.pluginKey, actionName);\n      }\n\n      const context = this.buildActionContext(config.pluginKey, contextOverride);\n      const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n      // 打印入参\n      this.logger.log('Executing capability (stream)', {\n        ...loggerContext,\n        is_stream: isStream,\n        input: stringifyForLog(input),\n      });\n\n      if (isStream && pluginInstance.runStream) {\n        // 流式 action：透传 AsyncIterable，同时收集 chunks\n        for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {\n          chunks.push(chunk);\n          yield chunk;\n        }\n      } else {\n        // 非流式 action：包装为单次 yield\n        const result = await pluginInstance.run(actionName, context, resolvedParams);\n        chunks.push(result);\n        yield result;\n      }\n\n      const durationMs = Date.now() - startTime;\n\n      // 打印聚合结果\n      const aggregatedResult = pluginInstance.aggregate\n        ? pluginInstance.aggregate(actionName, chunks)\n        : chunks;\n      this.logger.log('Capability (stream) executed successfully', {\n        ...loggerContext,\n        duration_ms: durationMs,\n        output: stringifyForLog(aggregatedResult),\n      });\n\n      this.reportCallEvent(config.pluginKey, true, durationMs, isStream, contextOverride);\n    } catch (error) {\n      const durationMs = Date.now() - startTime;\n\n      this.logger.error('Capability (stream) execution failed', {\n        ...loggerContext,\n        duration_ms: durationMs,\n        error: error instanceof Error ? error.message : String(error),\n      });\n\n      const errorCode = String((error as any)?.code ?? 'EXECUTION_ERROR');\n      this.reportCallEvent(config.pluginKey, false, durationMs, true, contextOverride, errorCode);\n\n      const displayName = this.pluginLoaderService.getManifest(config.pluginKey)?.displayName;\n      const formattedMessage = formatPluginError(error, displayName);\n      if (formattedMessage && error instanceof Error) {\n        error.message = formattedMessage;\n      }\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    const loggerContext = {\n      capability_id: config.id,\n      plugin_key: config.pluginKey,\n      action: actionName,\n    };\n    const chunks: unknown[] = [];\n    try {\n      this.validateRequiredParams(input, config.paramsSchema, config.name, contextOverride?.isDebug ?? false);\n      const { pluginInstance, resolvedParams } = await this.loadPluginAndResolveParams(config, input);\n\n      if (!pluginInstance.hasAction(actionName)) {\n        throw new ActionNotFoundError(config.pluginKey, actionName);\n      }\n\n      const context = this.buildActionContext(config.pluginKey, contextOverride);\n      const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;\n\n      // 打印入参\n      this.logger.log('Executing capability (streamWithEvents)', {\n        ...loggerContext,\n        is_stream: isStream,\n        input: stringifyForLog(input),\n      });\n\n      // 优先使用 runStreamWithEvents\n      if (pluginInstance.runStreamWithEvents) {\n        for await (const event of pluginInstance.runStreamWithEvents(actionName, context, resolvedParams)) {\n          // 收集 data 事件的数据用于聚合\n          if (event.type === 'data') {\n            chunks.push(event.data);\n            yield event;\n          } else if (event.type === 'done') {\n            // 拦截 done 事件，添加聚合结果\n            const aggregatedResult = pluginInstance.aggregate\n              ? pluginInstance.aggregate(actionName, chunks)\n              : chunks;\n\n            // 上报必须在 yield done 之前，因为 controller 收到 done 后会 return 导致 generator 终止\n            const durationMs = Date.now() - startTime;\n            this.reportCallEvent(config.pluginKey, true, durationMs, isStream, contextOverride);\n\n            yield {\n              type: 'done',\n              metadata: {\n                ...event.metadata,\n                aggregated: aggregatedResult,\n              },\n            };\n          } else {\n            yield event;\n          }\n        }\n      } else {\n        // 回退：包装 runStream 或 run 为 StreamEvent\n        if (isStream && pluginInstance.runStream) {\n          // 流式 action：包装每个 chunk 为 data 事件\n          for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {\n            chunks.push(chunk);\n            yield { type: 'data', data: chunk };\n          }\n        } else {\n          // 非流式 action：包装结果为单个 data 事件\n          const result = await pluginInstance.run(actionName, context, resolvedParams);\n          chunks.push(result);\n          yield { type: 'data', data: result };\n        }\n\n        // 聚合结果\n        const aggregatedResult = pluginInstance.aggregate\n          ? pluginInstance.aggregate(actionName, chunks)\n          : chunks;\n\n        // 上报必须在 yield done 之前\n        const durationMs = Date.now() - startTime;\n        this.reportCallEvent(config.pluginKey, true, durationMs, isStream, contextOverride);\n\n        // 发送 done 事件（包含聚合结果）\n        yield {\n          type: 'done',\n          metadata: {\n            chunks: chunks.length,\n            duration: durationMs,\n            aggregated: aggregatedResult,\n          },\n        };\n      }\n\n      // 打印聚合结果\n      const aggregatedResult = pluginInstance.aggregate\n        ? pluginInstance.aggregate(actionName, chunks)\n        : chunks;\n      this.logger.log('Capability (streamWithEvents) executed successfully', {\n        ...loggerContext,\n        duration_ms: Date.now() - startTime,\n        output: stringifyForLog(aggregatedResult),\n      });\n    } catch (error) {\n      const durationMs = Date.now() - startTime;\n\n      this.logger.error('Capability (streamWithEvents) execution failed', {\n        ...loggerContext,\n        duration_ms: durationMs,\n        error: error instanceof Error ? error.message : String(error),\n      });\n\n      // 上报必须在 yield error 之前\n      const errorCode = String((error as any)?.code ?? 'EXECUTION_ERROR');\n      this.reportCallEvent(config.pluginKey, false, durationMs, true, contextOverride, errorCode);\n\n      // 发送 error 事件\n      yield {\n        type: 'error',\n        error: this.extractErrorInfo(error, config.pluginKey),\n      };\n    }\n  }\n\n  /**\n   * 上报调用事件（fire-and-forget）\n   */\n  private reportCallEvent(\n    pluginKey: string,\n    success: boolean,\n    durationMs: number,\n    isStream: boolean,\n    contextOverride?: Partial<PluginActionContext>,\n    statusCode = '0',\n  ): void {\n    const callerType: CallerType = contextOverride?.caller\n      ?? (contextOverride?.isDebug ? 'debug' : 'server');\n    const manifest = this.pluginLoaderService.getManifest(pluginKey);\n    this.telemetryService.reportCall(pluginKey, {\n      version: manifest?.version ?? '',\n      success: String(success),\n      duration: String(durationMs),\n      is_stream: String(isStream),\n      caller_type: String(callerType),\n      status_code: statusCode,\n    }).catch(() => {\n      // 静默忽略上报失败\n    });\n  }\n\n  /**\n   * 从错误对象提取错误信息\n   * 支持 PluginError 和 RateLimitError\n   * @param error - 捕获到的错误\n   * @param pluginKey - 插件 key，用于获取 displayName 格式化 PluginError 消息\n   */\n  private extractErrorInfo(error: unknown, pluginKey?: string): {\n    code: string;\n    message: string;\n    rateLimitCode?: string;\n    rateLimitMessage?: string;\n  } {\n    const err = error as any;\n\n    // 获取错误码，默认为 EXECUTION_ERROR\n    const code = err?.code ?? 'EXECUTION_ERROR';\n    const message = err instanceof Error ? err.message : String(err);\n\n    // 如果是 RateLimitError，透传业务 code 和 message\n    if (code === 'RATE_LIMIT_EXCEEDED' && err?.rateLimitCode) {\n      return {\n        code,\n        message,\n        rateLimitCode: err.rateLimitCode,\n        rateLimitMessage: err.rateLimitMessage,\n      };\n    }\n\n    // 对 PluginError 格式化为中文消息\n    if (pluginKey) {\n      const displayName = this.pluginLoaderService.getManifest(pluginKey)?.displayName;\n      const formattedMessage = formatPluginError(error, displayName);\n      if (formattedMessage) {\n        return { code, message: formattedMessage };\n      }\n    }\n\n    return { code, message };\n  }\n\n  private buildActionContext(\n    pluginKey: string,\n    override?: Partial<PluginActionContext>,\n  ): PluginActionContext {\n    return {\n      pluginKey,\n      logger: this.logger,\n      platformHttpClient: this.createPluginHttpClient(pluginKey),\n      userContext: override?.userContext ?? this.getUserContext(),\n      isDebug: override?.isDebug ?? false,\n      caller: override?.caller,\n    };\n  }\n\n  /**\n   * 为指定插件创建独立的 HttpClient 实例\n   * 自动添加 x-plugin-key header\n   */\n  private createPluginHttpClient(pluginKey: string): PlatformHttpClient {\n    const client = this.httpClientFactory.create();\n\n    // 添加请求拦截器，注入 x-plugin-key header\n    client.interceptors.request.use((config) => {\n      config.headers = {\n        ...config.headers,\n        'x-plugin-key': pluginKey,\n      };\n      return config;\n    });\n\n    // 返回受保护的包装器，不暴露 interceptors\n    return this.wrapAsProtectedClient(client);\n  }\n\n  /**\n   * 将 HttpClient 包装为受保护的 PlatformHttpClient\n   * 只暴露请求方法，不暴露 interceptors\n   */\n  private wrapAsProtectedClient(client: HttpClientWithInterceptors): PlatformHttpClient {\n    return {\n      request: (config: any) => client.request(config),\n      get: (url: string, config?: any) => client.get(url, config),\n      post: (url: string, data?: any, config?: any) => client.post(url, data, config),\n      put: (url: string, data?: any, config?: any) => client.put(url, data, config),\n      patch: (url: string, data?: any, config?: any) => client.patch(url, data, config),\n      delete: (url: string, config?: any) => client.delete(url, config),\n    };\n  }\n\n  private getUserContext(): UserContext {\n    const ctx = this.requestContextService.getContext();\n    return {\n      appId: ctx?.appId ?? '',\n      userId: ctx?.userId ?? '',\n      tenantId: ctx?.tenantId ?? '',\n      isSystemAccount: ctx?.isSystemAccount ?? false,\n    };\n  }\n}\n","import { Injectable, Inject, Logger } from '@nestjs/common';\nimport {\n  PLATFORM_HTTP_CLIENT,\n  type PlatformHttpClient,\n} from '@lark-apaas/nestjs-common';\n\nconst TELEMETRY_PATH = '/api/v1/studio/innerapi/resource_events';\n\n/**\n * 事件类型\n */\nexport type EventType = 'install' | 'create_instance' | 'call';\n\n/**\n * 调用者类型\n */\nexport type CallerType = 'client' | 'server' | 'debug';\n\n/**\n * 资源事件\n */\nexport interface ResourceEvent {\n  resourceType: 'plugin';\n  resourceKey: string;\n  eventType: EventType;\n  details?: Record<string, string>;\n}\n\n/**\n * Call 事件详情\n */\nexport interface CallEventDetails {\n  version: string;\n  success: string;\n  duration: string;\n  is_stream: string;\n  caller_type: string;\n  status_code: string;\n}\n\n/**\n * 上报响应\n */\ninterface ReportResponse {\n  status_code: string;\n  message?: string;\n  data?: unknown;\n}\n\n/**\n * 插件遥测服务\n *\n * 负责上报插件生命周期事件到平台\n */\n@Injectable()\nexport class TelemetryService {\n  private readonly logger = new Logger(TelemetryService.name);\n\n  constructor(\n    @Inject(PLATFORM_HTTP_CLIENT) private readonly client: PlatformHttpClient,\n  ) {}\n\n  /**\n   * 上报事件到平台\n   *\n   * @param events - 事件列表\n   * @returns 是否上报成功\n   */\n  async reportEvents(events: ResourceEvent[]): Promise<boolean> {\n    if (events.length === 0) {\n      return true;\n    }\n\n    try {\n      const response = await this.client.post(TELEMETRY_PATH, { events });\n\n      if (!response.ok) {\n        this.logger.warn(`Failed to report events: ${response.status} ${response.statusText}`);\n        return false;\n      }\n\n      const result = (await response.json()) as ReportResponse;\n\n      if (result.status_code !== '0') {\n        this.logger.warn(`API error: ${result.message}`);\n        return false;\n      }\n\n      this.logger.debug(`Reported ${events.length} event(s) successfully`);\n      return true;\n    } catch (error) {\n      // 事件上报失败不应影响主流程\n      this.logger.warn(`Failed to report events: ${error instanceof Error ? error.message : error}`);\n      return false;\n    }\n  }\n\n  /**\n   * 上报插件调用事件\n   *\n   * @param pluginKey - 插件标识\n   * @param details - 调用详情\n   */\n  async reportCall(pluginKey: string, details: CallEventDetails): Promise<void> {\n    await this.reportEvents([\n      {\n        resourceType: 'plugin',\n        resourceKey: pluginKey,\n        eventType: 'call',\n        details: { ...details },\n      },\n    ]);\n  }\n}\n","/**\n * 日志工具函数\n */\n\nconst DEFAULT_MAX_LENGTH = 1000;\n\n/**\n * 截断字符串\n */\nfunction truncateString(str: string, maxLength: number): string {\n  if (str.length <= maxLength) {\n    return str;\n  }\n  return str.slice(0, maxLength) + `... [truncated, total ${str.length} chars]`;\n}\n\n/**\n * 将对象转换为可打印的字符串，超过指定长度时截断\n * @param value - 要打印的值\n * @param maxLength - 最大字符数，默认 1000\n */\nexport function stringifyForLog(value: unknown, maxLength: number = DEFAULT_MAX_LENGTH): string {\n  try {\n    const str = JSON.stringify(value, null, 2);\n    return truncateString(str, maxLength);\n  } catch {\n    // 处理循环引用等情况\n    const str = String(value);\n    return truncateString(str, maxLength);\n  }\n}\n","/**\n * Migration Adaptor\n *\n * 用于迁移老版本 capability 调用代码，将新版本的返回结果包装为老版本的 Response 结构\n */\n\n/**\n * 失败输出结构\n */\nexport interface FailureOutput {\n  response: {\n    status: {\n      /** 协议层返回码（如 HTTP 状态码） */\n      protocolStatusCode: string;\n      /** 业务应用状态码 */\n      appStatusCode: string;\n    };\n    /** 返回体（JSON 字符串形式） */\n    body: string;\n  };\n}\n\n/**\n * 老版本 capability 调用的 Response 结构\n *\n * 注意：output 使用 any 类型以简化迁移代码，避免类型断言\n */\nexport interface MigrationResponse {\n  /** 当 code=0 时表示执行成功，当 code!=0 时表示执行失败 */\n  code: number;\n  data?: {\n    /** 执行成功时的输出结果（any 类型，兼容迁移场景） */\n    output?: any;\n    /** 执行结果，'success' 或 'error' */\n    outcome?: 'success' | 'error';\n    /** 执行失败时的输出结果 */\n    failureOutput?: FailureOutput;\n  };\n  /** 发生错误时的错误信息 */\n  message?: string;\n}\n\n/**\n * 迁移适配器\n *\n * 将 CapabilityService.load().call() 的返回结果包装为老版本的 Response 结构\n *\n * @example\n * // 老代码\n * const result = await generateTaskDescription(params);\n *\n * // 新代码\n * const result = await migrationAdaptor(\n *   this.capabilityService.load('ai_generate_task_description').call('run', params)\n * );\n *\n * // result 结构\n * // {\n * //   code: 0,\n * //   data: {\n * //     output: { ... },  // 能力执行结果\n * //     outcome: 'success'\n * //   }\n * // }\n */\nexport async function migrationAdaptor(\n  promise: Promise<unknown>,\n): Promise<MigrationResponse> {\n  try {\n    const result = await promise;\n\n    return {\n      code: 0,\n      data: {\n        output: result,\n        outcome: 'success',\n      },\n    };\n  } catch (error) {\n    const errorMessage = error instanceof Error ? error.message : String(error);\n    const appStatusCode = error instanceof Error && 'code' in error ? String(error.code) : 'EXECUTION_ERROR';\n\n    return {\n      code: -1,\n      data: {\n        outcome: 'error',\n        failureOutput: {\n          response: {\n            status: {\n              protocolStatusCode: '500',\n              appStatusCode,\n            },\n            body: JSON.stringify({\n              error: errorMessage,\n              stack: error instanceof Error ? error.stack : undefined,\n            }),\n          },\n        },\n      },\n      message: errorMessage,\n    };\n  }\n}\n","/**\n * PluginError 中文化格式化工具\n *\n * 在 capability 层拦截插件抛出的 PluginError，\n * 结合 manifest.displayName 生成用户可读的中文错误信息。\n * 无需修改任何插件，所有插件零改动即可生效。\n */\n\n// PluginError 的 code 枚举值（与 action-plugin-core 保持一致，用 duck typing 识别）\nconst PLUGIN_ERROR_CODES = new Set([\n  'INVALID_INPUT',\n  'EXECUTION_ERROR',\n  'INVALID_OUTPUT',\n  'INVALID_CONFIG',\n  'ACTION_NOT_FOUND',\n]);\n\n/**\n * 判断是否是 PluginError（duck typing，不依赖 instanceof）\n */\nfunction isPluginError(error: unknown): boolean {\n  if (!error || typeof error !== 'object') return false;\n  const code = (error as any).code;\n  return typeof code === 'string' && PLUGIN_ERROR_CODES.has(code);\n}\n\n/**\n * 将 PluginError 格式化为面向用户的中文消息\n * @param error - 捕获到的错误对象\n * @param displayName - 插件中文名（来自 manifest.displayName）\n * @returns 格式化后的中文消息，如果不是 PluginError 则返回 null\n */\nexport function formatPluginError(error: unknown, displayName?: string): string | null {\n  if (!isPluginError(error)) return null;\n\n  const err = error as any;\n  const label = displayName ? `「${displayName}」` : '';\n\n  switch (err.code) {\n    case 'INVALID_INPUT':\n      return `${label}插件输入校验失败: ${formatZodIssuesChinese(err.details)}`;\n\n    case 'INVALID_OUTPUT':\n      return `${label}插件输出校验失败: ${formatZodIssuesChinese(err.details)}`;\n\n    case 'INVALID_CONFIG':\n      return `${label}插件配置校验失败: ${formatZodIssuesChinese(err.details)}`;\n\n    case 'ACTION_NOT_FOUND':\n      return `${label}插件操作不存在`;\n\n    case 'EXECUTION_ERROR': {\n      // 如果插件内部有有意义的 message，透传\n      const inner = err.originalError instanceof Error ? err.originalError.message : '';\n      return inner\n        ? `${label}插件执行失败: ${inner}`\n        : `${label}插件执行失败`;\n    }\n\n    default:\n      return `${label}插件执行失败`;\n  }\n}\n\n/**\n * 将 ZodIssue 数组格式化为中文可读字符串\n */\nexport function formatZodIssuesChinese(details: unknown): string {\n  if (!Array.isArray(details) || details.length === 0) return '参数格式校验出错';\n  return details.map(translateZodIssue).join('；');\n}\n\nfunction translateZodIssue(issue: any): string {\n  const field = issue.path?.length > 0 ? `「${issue.path.join('.')}」` : '';\n\n  switch (issue.code) {\n    case 'invalid_type': {\n      const received = issue.received;\n      if (received === 'undefined' || received === 'null') {\n        return `${field}字段是必填的`;\n      }\n      return `${field}字段类型错误，期望${translateType(issue.expected)}`;\n    }\n\n    case 'too_small': {\n      if (issue.type === 'string') {\n        if (issue.minimum === 1) return `${field}字段不能为空`;\n        return `${field}字段长度不能少于 ${issue.minimum} 个字符`;\n      }\n      if (issue.type === 'number') return `${field}字段不能小于 ${issue.minimum}`;\n      if (issue.type === 'array') return `${field}字段至少需要 ${issue.minimum} 项`;\n      return `${field}字段值过小`;\n    }\n\n    case 'too_big': {\n      if (issue.type === 'string') return `${field}字段长度不能超过 ${issue.maximum} 个字符`;\n      if (issue.type === 'number') return `${field}字段不能大于 ${issue.maximum}`;\n      if (issue.type === 'array') return `${field}字段最多 ${issue.maximum} 项`;\n      return `${field}字段值过大`;\n    }\n\n    case 'invalid_string': {\n      if (issue.validation === 'email') return `${field}字段不是有效的邮箱地址`;\n      if (issue.validation === 'url') return `${field}字段不是有效的 URL`;\n      if (issue.validation === 'regex') return `${field}字段格式不正确`;\n      return `${field}字段格式校验出错`;\n    }\n\n    case 'invalid_enum_value':\n      return `${field}字段值不在允许的范围内`;\n\n    case 'unrecognized_keys':\n      return `包含未知字段: ${issue.keys?.join(', ')}`;\n\n    default:\n      return field ? `${field}字段格式校验出错` : '输入格式校验出错';\n  }\n}\n\nfunction translateType(type: string): string {\n  const map: Record<string, string> = {\n    string: '文本',\n    number: '数字',\n    boolean: '布尔值',\n    array: '数组',\n    object: '对象',\n    integer: '整数',\n  };\n  return map[type] || type;\n}\n","import {\n  Controller,\n  Post,\n  Get,\n  Param,\n  Body,\n  Res,\n  HttpStatus,\n  Logger,\n} from '@nestjs/common';\nimport { ApiExcludeController } from '@nestjs/swagger';\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';\nimport { stringifyForLog } from '../utils';\n\ninterface DebugRequestBody {\n  action?: string;\n  params?: Record<string, unknown>;\n  capability?: CapabilityConfig;\n}\n\n@ApiExcludeController()\n@Controller('__innerapi__/capability')\nexport class DebugController {\n  private readonly logger = new Logger(DebugController.name);\n\n  constructor(\n    private readonly capabilityService: CapabilityService,\n    private readonly pluginLoaderService: PluginLoaderService,\n    private readonly templateEngineService: TemplateEngineService,\n  ) {}\n\n  @Get('list')\n  list(@Res() res: Response): void {\n    try {\n      const capabilities = this.capabilityService.listCapabilities();\n\n      res.status(HttpStatus.OK).json({\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      } satisfies SuccessResponse<ListResponseData>);\n    } catch (error) {\n      this.logger.error('Failed to list capabilities', error);\n      res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({\n        status_code: ErrorCodes.EXECUTION_ERROR,\n        error_msg: `Failed to list capabilities: ${error instanceof Error ? error.message : String(error)}`,\n      } satisfies ErrorResponse);\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 CapabilityNotFoundError(capabilityId);\n    }\n\n    return config;\n  }\n\n  /**\n   * 获取 action 名称\n   * 优先使用传入的 action，否则使用插件第一个 action\n   */\n  private async getActionName(pluginKey: string, formValue?: unknown, bodyAction?: string): Promise<string> {\n    if (bodyAction) {\n      return bodyAction;\n    }\n\n    // 根据 manifest 决定是否传入 config\n    const isConfigRequired = this.pluginLoaderService.isConfigRequired(pluginKey);\n    const pluginInstance = isConfigRequired\n      ? await this.pluginLoaderService.loadPlugin(pluginKey, formValue)\n      : await this.pluginLoaderService.loadPlugin(pluginKey);\n\n    const actions = pluginInstance.listActions();\n\n    if (actions.length === 0) {\n      throw new Error(`Plugin ${pluginKey} has no actions`);\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    @Res() res: Response,\n  ): Promise<void> {\n    const startTime = Date.now();\n    const params = body.params ?? {};\n\n    try {\n      const config = this.getCapabilityConfig(capabilityId, body.capability);\n      const action = await this.getActionName(config.pluginKey, config.formValue, body.action);\n\n      const resolvedParams = this.templateEngineService.resolve(\n        config.formValue,\n        params,\n        config.paramsSchema,\n      );\n\n      const result = await this.capabilityService\n        .loadWithConfig(config)\n        .call(action, params, { isDebug: true, caller: 'debug' });\n\n      res.status(HttpStatus.OK).json({\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      } satisfies SuccessResponse<DebugExecuteResponseData>);\n    } catch (error) {\n      this.logger.error('Debug execution failed', error);\n      res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(\n        this.buildErrorResponse(error),\n      );\n    }\n  }\n\n  /**\n   * 构建错误响应\n   */\n  private buildErrorResponse(error: unknown): ErrorResponse {\n    if (error instanceof CapabilityNotFoundError) {\n      return {\n        status_code: ErrorCodes.CAPABILITY_NOT_FOUND,\n        error_msg: `Capability not found: ${error.capabilityId}`,\n      };\n    }\n    if (error instanceof PluginNotFoundError) {\n      return {\n        status_code: ErrorCodes.PLUGIN_NOT_FOUND,\n        error_msg: `Plugin not found, please install plugin: ${error.pluginKey}`,\n      };\n    }\n    if (error instanceof ActionNotFoundError) {\n      return {\n        status_code: ErrorCodes.ACTION_NOT_FOUND,\n        error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`,\n      };\n    }\n    // 处理 RateLimitError - 使用业务错误码作为 status_code\n    const err = error as any;\n    if (err?.code === 'RATE_LIMIT_EXCEEDED' && err?.rateLimitCode) {\n      return {\n        status_code: err.rateLimitCode,\n        error_msg: err.rateLimitMessage || err.message,\n        is_rate_limit_error: true,\n      };\n    }\n    return {\n      status_code: ErrorCodes.EXECUTION_ERROR,\n      error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`,\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, config.formValue, body.action);\n      const loggerContext = {\n        capability_id: config.id,\n        plugin_key: config.pluginKey,\n        action,\n      };\n\n      // 打印入参\n      this.logger.log(`Executing capability (stream)`, {\n        ...loggerContext,\n        input: stringifyForLog(params),\n      });\n\n      const capability = this.capabilityService.loadWithConfig(config);\n      const eventStream = capability.callStreamWithEvents(action, params, { isDebug: true, caller: 'debug' });\n\n      // 延迟发送策略：缓存上一个 chunk，收到下一个 data 或 done 时再发送\n      // 这样可以在最后一个 chunk 上标记 finished: true\n      let pendingChunk: unknown | null = null;\n\n      for await (const event of eventStream) {\n        switch (event.type) {\n          case 'data': {\n            // 先发送上一个缓存的 chunk（如果有）\n            if (pendingChunk !== null) {\n              const response: StreamContentResponse = {\n                status_code: ErrorCodes.SUCCESS,\n                data: {\n                  type: 'content',\n                  delta: pendingChunk,  // 直接透传 OutputSchema\n                },\n              };\n              res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n            }\n            // 缓存当前 chunk\n            pendingChunk = event.data;\n            break;\n          }\n\n          case 'done': {\n            // 发送最后一个 chunk 并带上 finished: true\n            if (pendingChunk !== null) {\n              const response: StreamContentResponse = {\n                status_code: ErrorCodes.SUCCESS,\n                data: {\n                  type: 'content',\n                  delta: pendingChunk,  // 直接透传 OutputSchema\n                  finished: true,\n                },\n              };\n              res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n            }\n            // 打印聚合结果（从 done 事件的 metadata 中获取）\n            this.logger.log(`Capability (stream) executed successfully`, {\n              ...loggerContext,\n              duration_ms: event.metadata.duration,\n              output: stringifyForLog(event.metadata.aggregated),\n            });\n            res.end();\n            return;\n          }\n\n          case 'error': {\n            // 错误事件：发送错误信息\n            // RateLimitError 使用业务错误码\n            const isRateLimitError = event.error.code === 'RATE_LIMIT_EXCEEDED' && !!event.error.rateLimitCode;\n            const response: StreamErrorResponse = {\n              status_code: ErrorCodes.SUCCESS,\n              data: {\n                type: 'error',\n                error: {\n                  code: isRateLimitError ? event.error.rateLimitCode! : event.error.code,\n                  message: isRateLimitError ? event.error.rateLimitMessage! : event.error.message,\n                  isRateLimitError: isRateLimitError || undefined,\n                },\n              },\n            };\n            res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n            res.end();\n            return;\n          }\n        }\n      }\n\n      // 如果事件流正常结束但没有 done 事件，发送缓存的 chunk\n      if (pendingChunk !== null) {\n        const response: StreamContentResponse = {\n          status_code: ErrorCodes.SUCCESS,\n          data: {\n            type: 'content',\n            delta: pendingChunk,  // 直接透传 OutputSchema\n            finished: true,\n          },\n        };\n        res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n      }\n      res.end();\n    } catch (error) {\n      // 流异常中断（在事件流开始前的错误）\n      const err = error as any;\n      const isRateLimitError = err?.code === 'RATE_LIMIT_EXCEEDED' && !!err?.rateLimitCode;\n      const response: StreamErrorResponse = {\n        status_code: ErrorCodes.SUCCESS,\n        data: {\n          type: 'error',\n          error: {\n            code: isRateLimitError ? err.rateLimitCode : (err?.code ?? 'EXECUTION_ERROR'),\n            message: isRateLimitError ? err.rateLimitMessage : (error instanceof Error ? error.message : String(error)),\n            isRateLimitError: isRateLimitError || undefined,\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  HttpStatus,\n  Logger,\n} from '@nestjs/common';\nimport { ApiExcludeController } from '@nestjs/swagger';\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';\nimport { stringifyForLog } from '../utils';\n\ninterface ExecuteRequestBody {\n  action: string;\n  params: Record<string, unknown>;\n}\n@ApiExcludeController()\n@Controller('api/capability')\nexport class WebhookController {\n  private readonly logger = new Logger(WebhookController.name);\n\n  constructor(private readonly capabilityService: CapabilityService) {}\n\n  @Get('list')\n  list(@Res() res: Response): void {\n    try {\n      const capabilities = this.capabilityService.listCapabilities();\n      res.status(HttpStatus.OK).json({\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      } satisfies SuccessResponse<ListResponseData>);\n    } catch (error) {\n      this.logger.error('Failed to list capabilities', error);\n      res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({\n        status_code: ErrorCodes.EXECUTION_ERROR,\n        error_msg: `Failed to list capabilities: ${error instanceof Error ? error.message : String(error)}`,\n      } satisfies ErrorResponse);\n    }\n  }\n\n  @Post(':capability_id')\n  async execute(\n    @Param('capability_id') capabilityId: string,\n    @Body() body: ExecuteRequestBody,\n    @Res() res: Response,\n  ): Promise<void> {\n    try {\n      const result = await this.capabilityService\n        .load(capabilityId)\n        .call(body.action, body.params, { caller: 'client' });\n\n      res.status(HttpStatus.OK).json({\n        status_code: ErrorCodes.SUCCESS,\n        data: {\n          output: result,\n        },\n      } satisfies SuccessResponse<ExecuteResponseData>);\n    } catch (error) {\n      this.logger.error('Capability execution failed', error);\n      res.status(HttpStatus.INTERNAL_SERVER_ERROR).json(\n        this.buildErrorResponse(error),\n      );\n    }\n  }\n\n  /**\n   * 构建错误响应\n   */\n  private buildErrorResponse(error: unknown): ErrorResponse {\n    if (error instanceof CapabilityNotFoundError) {\n      return {\n        status_code: ErrorCodes.CAPABILITY_NOT_FOUND,\n        error_msg: `Capability not found: ${error.capabilityId}`,\n      };\n    }\n    if (error instanceof PluginNotFoundError) {\n      return {\n        status_code: ErrorCodes.PLUGIN_NOT_FOUND,\n        error_msg: `Plugin not found, please install plugin: ${error.pluginKey}`,\n      };\n    }\n    if (error instanceof ActionNotFoundError) {\n      return {\n        status_code: ErrorCodes.ACTION_NOT_FOUND,\n        error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`,\n      };\n    }\n    // 处理 RateLimitError - 使用业务错误码作为 status_code\n    const err = error as any;\n    if (err?.code === 'RATE_LIMIT_EXCEEDED' && err?.rateLimitCode) {\n      return {\n        status_code: err.rateLimitCode,\n        error_msg: err.rateLimitMessage || err.message,\n        is_rate_limit_error: true,\n      };\n    }\n    return {\n      status_code: ErrorCodes.EXECUTION_ERROR,\n      error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`,\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    const loggerContext = {\n      capability_id: capabilityId,\n      action: body.action,\n    };\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      // 打印入参\n      this.logger.log(`Executing capability (stream)`, {\n        ...loggerContext,\n        input: stringifyForLog(body.params),\n      });\n\n      const capability = this.capabilityService.load(capabilityId);\n      const eventStream = capability.callStreamWithEvents(body.action, body.params, { caller: 'client' });\n\n      // 延迟发送策略：缓存上一个 chunk，收到下一个 data 或 done 时再发送\n      // 这样可以在最后一个 chunk 上标记 finished: true\n      let pendingChunk: unknown | null = null;\n\n      for await (const event of eventStream) {\n        switch (event.type) {\n          case 'data': {\n            // 先发送上一个缓存的 chunk（如果有）\n            if (pendingChunk !== null) {\n              const response: StreamContentResponse = {\n                status_code: ErrorCodes.SUCCESS,\n                data: {\n                  type: 'content',\n                  delta: pendingChunk,  // 直接透传 OutputSchema\n                },\n              };\n              res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n            }\n            // 缓存当前 chunk\n            pendingChunk = event.data;\n            break;\n          }\n\n          case 'done': {\n            // 发送最后一个 chunk 并带上 finished: true\n            if (pendingChunk !== null) {\n              const response: StreamContentResponse = {\n                status_code: ErrorCodes.SUCCESS,\n                data: {\n                  type: 'content',\n                  delta: pendingChunk,  // 直接透传 OutputSchema\n                  finished: true,\n                },\n              };\n              res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n            }\n            // 打印聚合结果（从 done 事件的 metadata 中获取）\n            this.logger.log(`Capability (stream) executed successfully`, {\n              ...loggerContext,\n              duration_ms: event.metadata.duration,\n              output: stringifyForLog(event.metadata.aggregated),\n            });\n            res.end();\n            return;\n          }\n\n          case 'error': {\n            // 错误事件：发送错误信息\n            // RateLimitError 使用业务错误码\n            const isRateLimitError = event.error.code === 'RATE_LIMIT_EXCEEDED' && !!event.error.rateLimitCode;\n            const response: StreamErrorResponse = {\n              status_code: ErrorCodes.SUCCESS,\n              data: {\n                type: 'error',\n                error: {\n                  code: isRateLimitError ? event.error.rateLimitCode! : event.error.code,\n                  message: isRateLimitError ? event.error.rateLimitMessage! : event.error.message,\n                  isRateLimitError: isRateLimitError || undefined,\n                },\n              },\n            };\n            res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n            res.end();\n            return;\n          }\n        }\n      }\n\n      // 如果事件流正常结束但没有 done 事件，发送缓存的 chunk\n      if (pendingChunk !== null) {\n        const response: StreamContentResponse = {\n          status_code: ErrorCodes.SUCCESS,\n          data: {\n            type: 'content',\n            delta: pendingChunk,  // 直接透传 OutputSchema\n            finished: true,\n          },\n        };\n        res.write(`data: ${JSON.stringify(response)}\\n\\n`);\n      }\n      res.end();\n    } catch (error) {\n      // 流异常中断（在事件流开始前的错误）\n      const err = error as any;\n      const isRateLimitError = err?.code === 'RATE_LIMIT_EXCEEDED' && !!err?.rateLimitCode;\n      const response: StreamErrorResponse = {\n        status_code: ErrorCodes.SUCCESS,\n        data: {\n          type: 'error',\n          error: {\n            code: isRateLimitError ? err.rateLimitCode : (err?.code ?? 'EXECUTION_ERROR'),\n            message: isRateLimitError ? err.rateLimitMessage : (error instanceof Error ? error.message : String(error)),\n            isRateLimitError: isRateLimitError || undefined,\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  CommonModule,\n  RequestContextService,\n  HTTP_CLIENT_FACTORY,\n} from '@lark-apaas/nestjs-common';\nimport { DebugController, WebhookController } from './controllers';\nimport {\n  CapabilityService,\n  PluginLoaderService,\n  TemplateEngineService,\n  TelemetryService,\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  imports: [CommonModule],\n  controllers: getControllers(),\n  providers: [CapabilityService, PluginLoaderService, TemplateEngineService, TelemetryService],\n  exports: [CapabilityService, TelemetryService],\n})\nexport class CapabilityModule {\n  static forRoot(options?: CapabilityModuleOptions): DynamicModule {\n    return {\n      module: CapabilityModule,\n      imports: [CommonModule],\n      controllers: getControllers(),\n      providers: [\n        {\n          provide: CAPABILITY_OPTIONS,\n          useValue: options ?? {},\n        },\n        {\n          provide: CapabilityService,\n          useFactory: (\n            requestContextService: RequestContextService,\n            httpClientFactory: any,\n            pluginLoader: PluginLoaderService,\n            templateEngine: TemplateEngineService,\n            telemetryService: TelemetryService,\n            moduleOptions: CapabilityModuleOptions,\n          ) => {\n            const service = new CapabilityService(\n              requestContextService,\n              httpClientFactory,\n              pluginLoader,\n              templateEngine,\n              telemetryService,\n            );\n            // 设置模块配置（包括 capabilitiesDir、enableWatching、watchDebounce）\n            if (moduleOptions) {\n              service.setOptions(moduleOptions);\n            }\n            return service;\n          },\n          inject: [\n            RequestContextService,\n            HTTP_CLIENT_FACTORY,\n            PluginLoaderService,\n            TemplateEngineService,\n            TelemetryService,\n            CAPABILITY_OPTIONS,\n          ],\n        },\n        PluginLoaderService,\n        TemplateEngineService,\n        TelemetryService,\n      ],\n      exports: [CapabilityService, TelemetryService],\n    };\n  }\n}\n"],"mappings":"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","names":["getImportMetaUrl","document","URL","__filename","href","currentScript","tagName","toUpperCase","src","baseURI","importMetaUrl","ErrorCodes","SUCCESS","CAPABILITY_NOT_FOUND","PLUGIN_NOT_FOUND","ACTION_NOT_FOUND","PARAMS_VALIDATION_ERROR","EXECUTION_ERROR","RATE_LIMIT_EXCEEDED","TYPE_DEFAULT_VALUES","array","object","string","number","integer","boolean","null","TemplateEngineService","EXPR_REGEX","WHOLE_STRING_EXPR_REGEX","resolve","template","input","paramsSchema","resolveString","Array","isArray","map","item","resolveObject","wholeMatch","match","path","value","getValueByPath","undefined","defaultValue","getDefaultValueForPath","lastIndex","test","result","replace","String","key","Object","entries","obj","keys","split","current","schema","fieldSchema","getSchemaForPath","getDefaultValueFromSchema","currentSchema","properties","default","oneOf","anyOf","type","t","import_common","require","createRequire","PluginNotFoundError","Error","pluginKey","name","PluginLoadError","reason","PluginLoaderService","logger","Logger","pluginInstances","Map","pluginVersions","manifestCache","findPackageRoot","entryPath","dir","dirname","existsSync","join","getManifest","has","get","resolve","packageRoot","set","manifestPath","content","readFileSync","manifest","JSON","parse","isConfigRequired","form","refType","loadPlugin","config","createPluginInstance","cached","debug","instance","log","undefined","resolvedPath","version","fileUrl","pathToFileURL","href","importPath","mod","pluginPackage","default","create","error","code","message","String","isPluginInstalled","clearCache","delete","clearNodeModuleCache","Date","now","key","keys","clear","cache","clearModuleAndChildren","pluginScope","startsWith","split","slice","children","forEach","child","filename","includes","reloadPlugin","import_common","import_nestjs_common","fs","path","import_common","TELEMETRY_PATH","TelemetryService","logger","Logger","name","client","reportEvents","events","length","response","post","ok","warn","status","statusText","result","json","status_code","message","debug","error","Error","reportCall","pluginKey","details","resourceType","resourceKey","eventType","DEFAULT_MAX_LENGTH","truncateString","str","maxLength","length","slice","stringifyForLog","value","JSON","stringify","String","migrationAdaptor","promise","result","code","data","output","outcome","error","errorMessage","Error","message","String","appStatusCode","failureOutput","response","status","protocolStatusCode","body","JSON","stringify","stack","undefined","PLUGIN_ERROR_CODES","Set","isPluginError","error","code","has","formatPluginError","displayName","err","label","formatZodIssuesChinese","details","inner","originalError","Error","message","Array","isArray","length","map","translateZodIssue","join","issue","field","path","received","translateType","expected","type","minimum","maximum","validation","keys","string","number","boolean","array","object","integer","CapabilityNotFoundError","Error","capabilityId","name","ActionNotFoundError","pluginKey","actionName","RequiredParamMissingError","capabilityName","diagnostics","lines","map","d","field","detail","join","CapabilityService","logger","Logger","capabilities","Map","filePathToId","capabilitiesDir","fileWatcher","options","requestContextService","httpClientFactory","pluginLoaderService","templateEngineService","telemetryService","process","cwd","setOptions","setCapabilitiesDir","dir","onModuleInit","loadCapabilities","enableWatching","startWatching","onModuleDestroy","stopWatching","existsSync","warn","pattern","debounce","watchDebounce","log","watch","persistent","ignoreInitial","awaitWriteFinish","stabilityThreshold","pollInterval","on","filePath","handleFileAdd","handleFileChange","handleFileUnlink","error","close","reloadAllCapabilities","clear","loadCapabilityFromFile","get","config","clearCache","reloadCapabilityFromFile","removeCapabilityByFile","content","readFileSync","JSON","parse","id","set","oldId","oldConfig","delete","files","readdirSync","filter","f","endsWith","file","size","listCapabilities","Array","from","values","getCapability","load","createExecutor","loadWithConfig","call","input","contextOverride","executeCall","callStream","executeCallStream","callStreamWithEvents","executeCallStreamWithEvents","isStream","checkIsStream","loadPluginAndResolveParams","isConfigRequired","pluginInstance","loadPlugin","formValue","resolvedParams","resolve","paramsSchema","validateRequiredParams","isDebug","required","length","properties","params","fieldName","fieldSchema","value","schemaType","type","desc","description","undefined","push","reason","isArray","hasAction","isStreamAction","startTime","Date","now","loggerContext","capability_id","plugin_key","action","context","buildActionContext","is_stream","stringifyForLog","result","runStream","chunks","chunk","aggregate","run","durationMs","duration_ms","output","reportCallEvent","message","String","errorCode","code","displayName","getManifest","formattedMessage","formatPluginError","aggregatedResult","runStreamWithEvents","event","data","metadata","aggregated","duration","extractErrorInfo","success","statusCode","callerType","caller","manifest","reportCall","version","caller_type","status_code","catch","err","rateLimitCode","rateLimitMessage","override","platformHttpClient","createPluginHttpClient","userContext","getUserContext","client","create","interceptors","request","use","headers","wrapAsProtectedClient","url","post","put","patch","ctx","getContext","appId","userId","tenantId","isSystemAccount","import_common","DebugController","logger","Logger","name","capabilityService","pluginLoaderService","templateEngineService","list","res","capabilities","listCapabilities","status","HttpStatus","OK","json","status_code","ErrorCodes","SUCCESS","data","map","c","id","pluginID","pluginKey","pluginVersion","error","INTERNAL_SERVER_ERROR","EXECUTION_ERROR","error_msg","Error","message","String","getCapabilityConfig","capabilityId","bodyCapability","config","getCapability","CapabilityNotFoundError","getActionName","formValue","bodyAction","isConfigRequired","pluginInstance","loadPlugin","actions","listActions","length","debug","body","startTime","Date","now","params","capability","action","resolvedParams","resolve","paramsSchema","result","loadWithConfig","call","isDebug","caller","output","capabilityConfig","duration","buildErrorResponse","CAPABILITY_NOT_FOUND","PluginNotFoundError","PLUGIN_NOT_FOUND","ActionNotFoundError","ACTION_NOT_FOUND","actionName","err","code","rateLimitCode","rateLimitMessage","is_rate_limit_error","debugStream","setHeader","loggerContext","capability_id","plugin_key","log","input","stringifyForLog","eventStream","callStreamWithEvents","pendingChunk","event","type","response","delta","write","JSON","stringify","finished","duration_ms","metadata","aggregated","end","isRateLimitError","undefined","import_common","import_swagger","WebhookController","logger","Logger","name","capabilityService","list","res","capabilities","listCapabilities","status","HttpStatus","OK","json","status_code","ErrorCodes","SUCCESS","data","map","c","id","pluginID","pluginKey","pluginVersion","error","INTERNAL_SERVER_ERROR","EXECUTION_ERROR","error_msg","Error","message","String","execute","capabilityId","body","result","load","call","action","params","caller","output","buildErrorResponse","CapabilityNotFoundError","CAPABILITY_NOT_FOUND","PluginNotFoundError","PLUGIN_NOT_FOUND","ActionNotFoundError","ACTION_NOT_FOUND","actionName","err","code","rateLimitCode","rateLimitMessage","is_rate_limit_error","executeStream","loggerContext","capability_id","setHeader","log","input","stringifyForLog","capability","eventStream","callStreamWithEvents","pendingChunk","event","type","response","delta","write","JSON","stringify","finished","duration_ms","metadata","duration","aggregated","end","isRateLimitError","undefined","import_common","import_nestjs_common","CAPABILITY_OPTIONS","Symbol","isDevelopment","process","env","NODE_ENV","getControllers","controllers","WebhookController","push","DebugController","CapabilityModule","forRoot","options","module","imports","CommonModule","providers","provide","useValue","CapabilityService","useFactory","requestContextService","httpClientFactory","pluginLoader","templateEngine","telemetryService","moduleOptions","service","setOptions","inject","RequestContextService","HTTP_CLIENT_FACTORY","PluginLoaderService","TemplateEngineService","TelemetryService","exports"]}