@lark-apaas/nestjs-capability 0.0.1-alpha.0 → 0.0.1-alpha.10

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.
package/dist/index.d.ts CHANGED
@@ -1,31 +1,19 @@
1
- import { Logger, OnModuleInit, DynamicModule } from '@nestjs/common';
1
+ import { Logger, OnModuleInit, OnModuleDestroy, DynamicModule } from '@nestjs/common';
2
2
  import { PlatformHttpClient, RequestContextService } from '@lark-apaas/nestjs-common';
3
3
  import { ZodSchema } from 'zod';
4
+ import { Response } from 'express';
4
5
 
5
6
  interface UserContext {
6
7
  userId: string;
7
8
  tenantId: string;
9
+ appId: string;
8
10
  }
9
11
  interface PluginActionContext {
10
12
  logger: Logger;
11
- httpClient: PlatformHttpClient;
13
+ platformHttpClient: PlatformHttpClient;
12
14
  userContext: UserContext;
13
- }
14
-
15
- interface ActionSchema {
16
- input: ZodSchema | ((config: unknown) => ZodSchema);
17
- output?: ZodSchema | ((input: unknown, config: unknown) => ZodSchema);
18
- }
19
- interface PluginInstance {
20
- run(actionName: string, context: PluginActionContext, input: unknown): Promise<unknown>;
21
- hasAction(actionName: string): boolean;
22
- getActionSchema(actionName: string): ActionSchema | null;
23
- getInputSchema(actionName: string, config?: unknown): ZodSchema | undefined;
24
- getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined;
25
- listActions(): string[];
26
- }
27
- interface PluginPackage {
28
- create(): PluginInstance;
15
+ /** 是否为调试模式(来自 debug controller 的调用) */
16
+ isDebug: boolean;
29
17
  }
30
18
 
31
19
  interface JSONSchema {
@@ -37,7 +25,7 @@ interface JSONSchema {
37
25
  }
38
26
  interface CapabilityConfig {
39
27
  id: string;
40
- pluginID: string;
28
+ pluginKey: string;
41
29
  pluginVersion: string;
42
30
  name: string;
43
31
  description: string;
@@ -47,8 +35,192 @@ interface CapabilityConfig {
47
35
  updatedAt: number;
48
36
  }
49
37
 
38
+ /**
39
+ * 成功响应基础结构
40
+ */
41
+ interface SuccessResponse<T> {
42
+ status_code: '0';
43
+ data: T;
44
+ }
45
+ /**
46
+ * 错误响应结构
47
+ */
48
+ interface ErrorResponse {
49
+ status_code: string;
50
+ error_msg: string;
51
+ }
52
+ /**
53
+ * Debug 信息
54
+ */
55
+ interface DebugInfo {
56
+ capabilityConfig: CapabilityConfig;
57
+ resolvedParams: unknown;
58
+ duration: number;
59
+ pluginID: string;
60
+ action: string;
61
+ }
62
+ /**
63
+ * 执行接口响应 data 结构
64
+ */
65
+ interface ExecuteResponseData {
66
+ output: unknown;
67
+ }
68
+ /**
69
+ * Debug 执行接口响应 data 结构
70
+ */
71
+ interface DebugExecuteResponseData {
72
+ output: unknown;
73
+ debug: DebugInfo;
74
+ }
75
+ /**
76
+ * 能力列表项
77
+ */
78
+ interface CapabilityListItem {
79
+ id: string;
80
+ name: string;
81
+ pluginID: string;
82
+ pluginVersion: string;
83
+ }
84
+ /**
85
+ * 列表接口响应 data 结构
86
+ */
87
+ interface ListResponseData {
88
+ capabilities: CapabilityListItem[];
89
+ }
90
+ /**
91
+ * 流式内容响应
92
+ */
93
+ interface StreamContentResponse {
94
+ status_code: '0';
95
+ data: {
96
+ type: 'content';
97
+ delta: unknown;
98
+ finished?: boolean;
99
+ };
100
+ }
101
+ /**
102
+ * 流式错误响应
103
+ */
104
+ interface StreamErrorResponse {
105
+ status_code: '0';
106
+ data: {
107
+ type: 'error';
108
+ error: {
109
+ code: number;
110
+ message: string;
111
+ };
112
+ };
113
+ }
114
+ /**
115
+ * 流式响应类型
116
+ */
117
+ type StreamResponse = StreamContentResponse | StreamErrorResponse;
118
+ /**
119
+ * 流完成元数据
120
+ */
121
+ interface StreamDoneMetadata {
122
+ /** chunk 总数 */
123
+ chunks: number;
124
+ /** 流持续时间 (ms) */
125
+ duration: number;
126
+ /** 聚合结果(可选) */
127
+ aggregated?: unknown;
128
+ }
129
+ /**
130
+ * 流错误信息
131
+ */
132
+ interface StreamError {
133
+ code: string;
134
+ message: string;
135
+ details?: unknown;
136
+ }
137
+ /**
138
+ * 流事件类型
139
+ * - data: 数据事件,包含单个 chunk
140
+ * - done: 完成事件,包含元数据
141
+ * - error: 错误事件,包含错误信息
142
+ */
143
+ type StreamEvent<T> = {
144
+ type: 'data';
145
+ data: T;
146
+ } | {
147
+ type: 'done';
148
+ metadata: StreamDoneMetadata;
149
+ } | {
150
+ type: 'error';
151
+ error: StreamError;
152
+ };
153
+
154
+ interface ActionSchema {
155
+ input: ZodSchema | ((config: unknown) => ZodSchema);
156
+ output?: ZodSchema | ((input: unknown, config: unknown) => ZodSchema);
157
+ }
158
+ interface PluginInstance {
159
+ /** 执行指定 action(unary) */
160
+ run(actionName: string, context: PluginActionContext, input: unknown): Promise<unknown>;
161
+ /** 检查 action 是否存在 */
162
+ hasAction(actionName: string): boolean;
163
+ /** 获取 action 的 schema */
164
+ getActionSchema(actionName: string): ActionSchema | null;
165
+ /** 获取解析后的 input schema */
166
+ getInputSchema(actionName: string, config?: unknown): ZodSchema | undefined;
167
+ /** 获取解析后的 output schema */
168
+ getOutputSchema(actionName: string, input: unknown, config?: unknown): ZodSchema | undefined;
169
+ /** 列出所有 action */
170
+ listActions(): string[];
171
+ /** 流式执行指定 action,返回原始流 */
172
+ runStream?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<unknown>;
173
+ /** 流式执行指定 action,返回带事件协议的流(推荐) */
174
+ runStreamWithEvents?(actionName: string, context: PluginActionContext, input: unknown): AsyncIterable<StreamEvent<unknown>>;
175
+ /** 检查 action 是否为流式 */
176
+ isStreamAction?(actionName: string): boolean;
177
+ /** 聚合流式结果(可选,插件自定义聚合逻辑) */
178
+ aggregate?(actionName: string, chunks: unknown[]): unknown;
179
+ }
180
+ interface PluginPackage {
181
+ create(): PluginInstance;
182
+ }
183
+
184
+ /**
185
+ * Capability 模块错误码
186
+ */
187
+ declare const ErrorCodes: {
188
+ /** 成功 */
189
+ readonly SUCCESS: "0";
190
+ /** 能力不存在 */
191
+ readonly CAPABILITY_NOT_FOUND: "k_ec_cap_001";
192
+ /** 插件不存在 */
193
+ readonly PLUGIN_NOT_FOUND: "k_ec_cap_002";
194
+ /** Action 不存在 */
195
+ readonly ACTION_NOT_FOUND: "k_ec_cap_003";
196
+ /** 参数验证失败 */
197
+ readonly PARAMS_VALIDATION_ERROR: "k_ec_cap_004";
198
+ /** 执行失败 */
199
+ readonly EXECUTION_ERROR: "k_ec_cap_005";
200
+ };
201
+ type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
202
+
203
+ /**
204
+ * 模板引擎服务
205
+ *
206
+ * 支持语法:
207
+ * - expr: '{{' + selector + '}}'
208
+ * - selector: 'input.' + ident | selector.ident
209
+ * - ident: [a-zA-Z_]([a-zA-Z_0-9])*
210
+ *
211
+ * 示例:
212
+ * - {{input.a}}
213
+ * - {{input.a.b}}
214
+ * - "this is {{input.a.b}}"
215
+ *
216
+ * 求值规则:
217
+ * - 如果整个字符串是单个表达式,保留原始类型
218
+ * - 如果是字符串插值(多个表达式或混合内容),返回字符串
219
+ * - 如果变量不存在,返回原始表达式
220
+ */
50
221
  declare class TemplateEngineService {
51
- private readonly TEMPLATE_REGEX;
222
+ private readonly EXPR_REGEX;
223
+ private readonly WHOLE_STRING_EXPR_REGEX;
52
224
  resolve(template: unknown, input: Record<string, unknown>): unknown;
53
225
  private resolveString;
54
226
  private resolveObject;
@@ -56,101 +228,201 @@ declare class TemplateEngineService {
56
228
  }
57
229
 
58
230
  declare class PluginNotFoundError extends Error {
59
- constructor(pluginID: string);
231
+ constructor(pluginKey: string);
60
232
  }
61
233
  declare class PluginLoadError extends Error {
62
- constructor(pluginID: string, reason: string);
234
+ constructor(pluginKey: string, reason: string);
63
235
  }
64
236
  declare class PluginLoaderService {
65
237
  private readonly logger;
66
238
  private readonly pluginInstances;
67
- loadPlugin(pluginID: string): PluginInstance;
68
- isPluginInstalled(pluginID: string): boolean;
69
- clearCache(pluginID?: string): void;
239
+ /** 记录每个插件的加载版本(时间戳),用于 ESM 缓存绕过 */
240
+ private readonly pluginVersions;
241
+ loadPlugin(pluginKey: string): Promise<PluginInstance>;
242
+ isPluginInstalled(pluginKey: string): boolean;
243
+ /**
244
+ * 清除插件缓存(包括 Node.js 模块缓存)
245
+ * @param pluginKey - 插件标识,不传则清除所有
246
+ */
247
+ clearCache(pluginKey?: string): void;
248
+ /**
249
+ * 清除 CJS 模块缓存
250
+ */
251
+ private clearNodeModuleCache;
252
+ /**
253
+ * 递归清除子模块缓存
254
+ */
255
+ private clearModuleAndChildren;
256
+ /**
257
+ * 强制重新加载插件
258
+ * @param pluginKey - 插件标识
259
+ */
260
+ reloadPlugin(pluginKey: string): Promise<PluginInstance>;
70
261
  }
71
262
 
72
263
  declare class CapabilityNotFoundError extends Error {
73
264
  constructor(capabilityId: string);
74
265
  }
75
266
  declare class ActionNotFoundError extends Error {
76
- constructor(pluginID: string, actionName: string);
267
+ constructor(pluginKey: string, actionName: string);
77
268
  }
78
269
  interface CapabilityExecutor {
270
+ /**
271
+ * 调用 capability(始终返回 Promise)
272
+ * - unary action: 直接返回结果
273
+ * - stream action: 内部聚合所有 chunk 后返回
274
+ */
79
275
  call(actionName: string, input: unknown, context?: Partial<PluginActionContext>): Promise<unknown>;
276
+ /**
277
+ * 流式调用 capability,返回原始流
278
+ * - 返回原始 AsyncIterable
279
+ * - 如果 action 是 unary,包装为单次 yield
280
+ */
281
+ callStream(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<unknown>;
282
+ /**
283
+ * 流式调用 capability,返回带事件协议的流(推荐)
284
+ * - 返回 StreamEvent 类型的 AsyncIterable
285
+ * - 支持 data/done/error 三种事件类型
286
+ * - Controller 层应优先使用此方法实现边收边发
287
+ */
288
+ callStreamWithEvents(actionName: string, input: unknown, context?: Partial<PluginActionContext>): AsyncIterable<StreamEvent<unknown>>;
289
+ /**
290
+ * 检查 action 是否为流式
291
+ */
292
+ isStream(actionName: string): Promise<boolean>;
80
293
  }
81
294
  interface CapabilityModuleOptions {
295
+ /** 能力配置目录路径,默认 server/capabilities */
82
296
  capabilitiesDir?: string;
297
+ /** 是否启用文件监听(热更新),默认 false */
298
+ enableWatching?: boolean;
299
+ /** 文件变更防抖时间(ms),默认 300 */
300
+ watchDebounce?: number;
83
301
  }
84
- declare class CapabilityService implements OnModuleInit {
302
+ declare class CapabilityService implements OnModuleInit, OnModuleDestroy {
85
303
  private readonly requestContextService;
86
- private readonly httpClient;
304
+ private readonly platformHttpClient;
87
305
  private readonly pluginLoaderService;
88
306
  private readonly templateEngineService;
89
307
  private readonly logger;
90
308
  private readonly capabilities;
309
+ /** 文件路径到 capability id 的映射,用于文件删除时查找 */
310
+ private readonly filePathToId;
91
311
  private capabilitiesDir;
92
- constructor(requestContextService: RequestContextService, httpClient: PlatformHttpClient, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService);
312
+ private fileWatcher;
313
+ private options;
314
+ constructor(requestContextService: RequestContextService, platformHttpClient: PlatformHttpClient, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService);
315
+ /**
316
+ * 设置模块配置
317
+ */
318
+ setOptions(options: CapabilityModuleOptions): void;
93
319
  setCapabilitiesDir(dir: string): void;
94
320
  onModuleInit(): Promise<void>;
321
+ onModuleDestroy(): Promise<void>;
322
+ /**
323
+ * 启动文件监听(沙箱环境自动调用)
324
+ */
325
+ startWatching(): void;
326
+ /**
327
+ * 停止文件监听
328
+ */
329
+ stopWatching(): void;
330
+ /**
331
+ * 重新加载所有能力配置
332
+ */
333
+ reloadAllCapabilities(): Promise<void>;
334
+ private handleFileAdd;
335
+ private handleFileChange;
336
+ private handleFileUnlink;
337
+ /**
338
+ * 从文件加载单个能力配置
339
+ */
340
+ private loadCapabilityFromFile;
341
+ /**
342
+ * 重新加载单个能力配置
343
+ */
344
+ private reloadCapabilityFromFile;
345
+ /**
346
+ * 根据文件路径移除能力配置
347
+ */
348
+ private removeCapabilityByFile;
95
349
  private loadCapabilities;
96
350
  listCapabilities(): CapabilityConfig[];
97
351
  getCapability(capabilityId: string): CapabilityConfig | null;
98
352
  load(capabilityId: string): CapabilityExecutor;
99
- private execute;
353
+ /**
354
+ * 使用传入的配置加载能力执行器
355
+ * 用于 debug 场景,支持用户传入自定义配置
356
+ */
357
+ loadWithConfig(config: CapabilityConfig): CapabilityExecutor;
358
+ private createExecutor;
359
+ /**
360
+ * 检查 action 是否为流式
361
+ */
362
+ private checkIsStream;
363
+ /**
364
+ * 执行 capability(始终返回 Promise)
365
+ * - unary action: 直接返回结果
366
+ * - stream action: 内部聚合所有 chunk 后返回
367
+ */
368
+ private executeCall;
369
+ /**
370
+ * 流式执行 capability
371
+ * - stream action: 返回原始 AsyncIterable
372
+ * - unary action: 包装为单次 yield
373
+ */
374
+ private executeCallStream;
375
+ /**
376
+ * 流式执行 capability,返回带事件协议的流
377
+ * - 优先使用 pluginInstance.runStreamWithEvents
378
+ * - 如果插件不支持,则包装 runStream/run 为 StreamEvent
379
+ */
380
+ private executeCallStreamWithEvents;
100
381
  private buildActionContext;
101
382
  private getUserContext;
102
383
  }
103
384
 
104
- interface ExecuteRequestBody$1 {
105
- action: string;
106
- params: Record<string, unknown>;
107
- }
108
- interface DebugResponse {
109
- code: number;
110
- message: string;
111
- data: unknown;
112
- debug?: {
113
- capabilityConfig: unknown;
114
- resolvedParams: unknown;
115
- duration: number;
116
- pluginID: string;
117
- };
118
- }
119
- interface ListResponse {
120
- code: number;
121
- message: string;
122
- data: Array<{
123
- id: string;
124
- name: string;
125
- pluginID: string;
126
- pluginVersion: string;
127
- }>;
385
+ interface DebugRequestBody {
386
+ action?: string;
387
+ params?: Record<string, unknown>;
388
+ capability?: CapabilityConfig;
128
389
  }
129
390
  declare class DebugController {
130
391
  private readonly capabilityService;
392
+ private readonly pluginLoaderService;
131
393
  private readonly templateEngineService;
132
- constructor(capabilityService: CapabilityService, templateEngineService: TemplateEngineService);
133
- list(): ListResponse;
134
- debug(capabilityId: string, body: ExecuteRequestBody$1): Promise<DebugResponse>;
394
+ private readonly logger;
395
+ constructor(capabilityService: CapabilityService, pluginLoaderService: PluginLoaderService, templateEngineService: TemplateEngineService);
396
+ list(): SuccessResponse<ListResponseData>;
397
+ /**
398
+ * 获取 capability 配置
399
+ * 优先使用 body.capability,否则从服务获取
400
+ */
401
+ private getCapabilityConfig;
402
+ /**
403
+ * 获取 action 名称
404
+ * 优先使用传入的 action,否则使用插件第一个 action
405
+ */
406
+ private getActionName;
407
+ debug(capabilityId: string, body: DebugRequestBody): Promise<SuccessResponse<DebugExecuteResponseData> | ErrorResponse>;
408
+ debugStream(capabilityId: string, body: DebugRequestBody, res: Response): Promise<void>;
135
409
  }
136
410
 
137
411
  interface ExecuteRequestBody {
138
412
  action: string;
139
413
  params: Record<string, unknown>;
140
414
  }
141
- interface ExecuteResponse {
142
- code: number;
143
- message: string;
144
- data: unknown;
145
- }
146
415
  declare class WebhookController {
147
416
  private readonly capabilityService;
417
+ private readonly logger;
148
418
  constructor(capabilityService: CapabilityService);
149
- execute(capabilityId: string, body: ExecuteRequestBody): Promise<ExecuteResponse>;
419
+ list(): SuccessResponse<ListResponseData>;
420
+ execute(capabilityId: string, body: ExecuteRequestBody): Promise<SuccessResponse<ExecuteResponseData> | ErrorResponse>;
421
+ executeStream(capabilityId: string, body: ExecuteRequestBody, res: Response): Promise<void>;
150
422
  }
151
423
 
152
424
  declare class CapabilityModule {
153
425
  static forRoot(options?: CapabilityModuleOptions): DynamicModule;
154
426
  }
155
427
 
156
- 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 };
428
+ 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 };