@lark-apaas/nestjs-capability 0.0.1-alpha.4 → 0.0.1-alpha.7
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.cjs +420 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +183 -67
- package/dist/index.d.ts +183 -67
- package/dist/index.js +422 -160
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
package/dist/index.cjs
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
CapabilityNotFoundError: () => CapabilityNotFoundError,
|
|
37
37
|
CapabilityService: () => CapabilityService,
|
|
38
38
|
DebugController: () => DebugController,
|
|
39
|
+
ErrorCodes: () => ErrorCodes,
|
|
39
40
|
PluginLoadError: () => PluginLoadError,
|
|
40
41
|
PluginLoaderService: () => PluginLoaderService,
|
|
41
42
|
PluginNotFoundError: () => PluginNotFoundError,
|
|
@@ -44,6 +45,22 @@ __export(index_exports, {
|
|
|
44
45
|
});
|
|
45
46
|
module.exports = __toCommonJS(index_exports);
|
|
46
47
|
|
|
48
|
+
// src/interfaces/error-codes.ts
|
|
49
|
+
var ErrorCodes = {
|
|
50
|
+
/** 成功 */
|
|
51
|
+
SUCCESS: "0",
|
|
52
|
+
/** 能力不存在 */
|
|
53
|
+
CAPABILITY_NOT_FOUND: "k_ec_cap_001",
|
|
54
|
+
/** 插件不存在 */
|
|
55
|
+
PLUGIN_NOT_FOUND: "k_ec_cap_002",
|
|
56
|
+
/** Action 不存在 */
|
|
57
|
+
ACTION_NOT_FOUND: "k_ec_cap_003",
|
|
58
|
+
/** 参数验证失败 */
|
|
59
|
+
PARAMS_VALIDATION_ERROR: "k_ec_cap_004",
|
|
60
|
+
/** 执行失败 */
|
|
61
|
+
EXECUTION_ERROR: "k_ec_cap_005"
|
|
62
|
+
};
|
|
63
|
+
|
|
47
64
|
// src/services/template-engine.service.ts
|
|
48
65
|
var import_common = require("@nestjs/common");
|
|
49
66
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -200,6 +217,28 @@ var import_common3 = require("@nestjs/common");
|
|
|
200
217
|
var import_nestjs_common = require("@lark-apaas/nestjs-common");
|
|
201
218
|
var fs = __toESM(require("fs"), 1);
|
|
202
219
|
var path = __toESM(require("path"), 1);
|
|
220
|
+
|
|
221
|
+
// src/utils/log-utils.ts
|
|
222
|
+
var DEFAULT_MAX_LENGTH = 1e3;
|
|
223
|
+
function truncateString(str, maxLength) {
|
|
224
|
+
if (str.length <= maxLength) {
|
|
225
|
+
return str;
|
|
226
|
+
}
|
|
227
|
+
return str.slice(0, maxLength) + `... [truncated, total ${str.length} chars]`;
|
|
228
|
+
}
|
|
229
|
+
__name(truncateString, "truncateString");
|
|
230
|
+
function stringifyForLog(value, maxLength = DEFAULT_MAX_LENGTH) {
|
|
231
|
+
try {
|
|
232
|
+
const str = JSON.stringify(value, null, 2);
|
|
233
|
+
return truncateString(str, maxLength);
|
|
234
|
+
} catch {
|
|
235
|
+
const str = String(value);
|
|
236
|
+
return truncateString(str, maxLength);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
__name(stringifyForLog, "stringifyForLog");
|
|
240
|
+
|
|
241
|
+
// src/services/capability.service.ts
|
|
203
242
|
function _ts_decorate3(decorators, target, key, desc) {
|
|
204
243
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
205
244
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -240,15 +279,15 @@ var CapabilityService = class _CapabilityService {
|
|
|
240
279
|
__name(this, "CapabilityService");
|
|
241
280
|
}
|
|
242
281
|
requestContextService;
|
|
243
|
-
|
|
282
|
+
platformHttpClient;
|
|
244
283
|
pluginLoaderService;
|
|
245
284
|
templateEngineService;
|
|
246
285
|
logger = new import_common3.Logger(_CapabilityService.name);
|
|
247
286
|
capabilities = /* @__PURE__ */ new Map();
|
|
248
287
|
capabilitiesDir;
|
|
249
|
-
constructor(requestContextService,
|
|
288
|
+
constructor(requestContextService, platformHttpClient, pluginLoaderService, templateEngineService) {
|
|
250
289
|
this.requestContextService = requestContextService;
|
|
251
|
-
this.
|
|
290
|
+
this.platformHttpClient = platformHttpClient;
|
|
252
291
|
this.pluginLoaderService = pluginLoaderService;
|
|
253
292
|
this.templateEngineService = templateEngineService;
|
|
254
293
|
this.capabilitiesDir = path.join(process.cwd(), "server/capabilities");
|
|
@@ -311,6 +350,9 @@ var CapabilityService = class _CapabilityService {
|
|
|
311
350
|
callStream: /* @__PURE__ */ __name((actionName, input, contextOverride) => {
|
|
312
351
|
return this.executeCallStream(config, actionName, input, contextOverride);
|
|
313
352
|
}, "callStream"),
|
|
353
|
+
callStreamWithEvents: /* @__PURE__ */ __name((actionName, input, contextOverride) => {
|
|
354
|
+
return this.executeCallStreamWithEvents(config, actionName, input, contextOverride);
|
|
355
|
+
}, "callStreamWithEvents"),
|
|
314
356
|
isStream: /* @__PURE__ */ __name(async (actionName) => {
|
|
315
357
|
return this.checkIsStream(config, actionName);
|
|
316
358
|
}, "isStream")
|
|
@@ -333,20 +375,23 @@ var CapabilityService = class _CapabilityService {
|
|
|
333
375
|
*/
|
|
334
376
|
async executeCall(config, actionName, input, contextOverride) {
|
|
335
377
|
const startTime = Date.now();
|
|
378
|
+
const loggerContext = {
|
|
379
|
+
capability_id: config.id,
|
|
380
|
+
plugin_key: config.pluginKey,
|
|
381
|
+
action: actionName
|
|
382
|
+
};
|
|
336
383
|
try {
|
|
337
384
|
const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);
|
|
338
385
|
if (!pluginInstance.hasAction(actionName)) {
|
|
339
386
|
throw new ActionNotFoundError(config.pluginKey, actionName);
|
|
340
387
|
}
|
|
341
|
-
const resolvedParams = this.templateEngineService.resolve(config.formValue, input);
|
|
388
|
+
const resolvedParams = config.formValue ? this.templateEngineService.resolve(config.formValue, input) : input;
|
|
342
389
|
const context = this.buildActionContext(contextOverride);
|
|
343
390
|
const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
|
|
344
|
-
this.logger.log({
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
pluginKey: config.pluginKey,
|
|
349
|
-
isStream
|
|
391
|
+
this.logger.log("Executing capability (call)", {
|
|
392
|
+
...loggerContext,
|
|
393
|
+
is_stream: isStream,
|
|
394
|
+
input: stringifyForLog(input)
|
|
350
395
|
});
|
|
351
396
|
let result;
|
|
352
397
|
if (isStream && pluginInstance.runStream) {
|
|
@@ -358,20 +403,17 @@ var CapabilityService = class _CapabilityService {
|
|
|
358
403
|
} else {
|
|
359
404
|
result = await pluginInstance.run(actionName, context, resolvedParams);
|
|
360
405
|
}
|
|
361
|
-
this.logger.log({
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
duration: Date.now() - startTime
|
|
406
|
+
this.logger.log("Capability (call) executed successfully", {
|
|
407
|
+
...loggerContext,
|
|
408
|
+
duration_ms: Date.now() - startTime,
|
|
409
|
+
output: stringifyForLog(result)
|
|
366
410
|
});
|
|
367
411
|
return result;
|
|
368
412
|
} catch (error) {
|
|
369
|
-
this.logger.error({
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
error: error instanceof Error ? error.message : String(error),
|
|
374
|
-
duration: Date.now() - startTime
|
|
413
|
+
this.logger.error("Capability (call) execution failed", {
|
|
414
|
+
...loggerContext,
|
|
415
|
+
duration_ms: Date.now() - startTime,
|
|
416
|
+
error: error instanceof Error ? error.message : String(error)
|
|
375
417
|
});
|
|
376
418
|
throw error;
|
|
377
419
|
}
|
|
@@ -383,54 +425,140 @@ var CapabilityService = class _CapabilityService {
|
|
|
383
425
|
*/
|
|
384
426
|
async *executeCallStream(config, actionName, input, contextOverride) {
|
|
385
427
|
const startTime = Date.now();
|
|
428
|
+
const loggerContext = {
|
|
429
|
+
capability_id: config.id,
|
|
430
|
+
plugin_key: config.pluginKey,
|
|
431
|
+
action: actionName
|
|
432
|
+
};
|
|
433
|
+
const chunks = [];
|
|
386
434
|
try {
|
|
387
435
|
const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);
|
|
388
436
|
if (!pluginInstance.hasAction(actionName)) {
|
|
389
437
|
throw new ActionNotFoundError(config.pluginKey, actionName);
|
|
390
438
|
}
|
|
391
|
-
const resolvedParams = this.templateEngineService.resolve(config.formValue, input);
|
|
439
|
+
const resolvedParams = config.formValue ? this.templateEngineService.resolve(config.formValue, input) : input;
|
|
392
440
|
const context = this.buildActionContext(contextOverride);
|
|
393
441
|
const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
|
|
394
|
-
this.logger.log({
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
pluginKey: config.pluginKey,
|
|
399
|
-
isStream
|
|
442
|
+
this.logger.log("Executing capability (stream)", {
|
|
443
|
+
...loggerContext,
|
|
444
|
+
is_stream: isStream,
|
|
445
|
+
input: stringifyForLog(input)
|
|
400
446
|
});
|
|
401
447
|
if (isStream && pluginInstance.runStream) {
|
|
402
|
-
|
|
448
|
+
for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {
|
|
449
|
+
chunks.push(chunk);
|
|
450
|
+
yield chunk;
|
|
451
|
+
}
|
|
403
452
|
} else {
|
|
404
453
|
const result = await pluginInstance.run(actionName, context, resolvedParams);
|
|
454
|
+
chunks.push(result);
|
|
405
455
|
yield result;
|
|
406
456
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
457
|
+
const aggregatedResult = pluginInstance.aggregate ? pluginInstance.aggregate(actionName, chunks) : chunks;
|
|
458
|
+
this.logger.log("Capability (stream) executed successfully", {
|
|
459
|
+
...loggerContext,
|
|
460
|
+
duration_ms: Date.now() - startTime,
|
|
461
|
+
output: stringifyForLog(aggregatedResult)
|
|
412
462
|
});
|
|
413
463
|
} catch (error) {
|
|
414
|
-
this.logger.error({
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
error: error instanceof Error ? error.message : String(error),
|
|
419
|
-
duration: Date.now() - startTime
|
|
464
|
+
this.logger.error("Capability (stream) execution failed", {
|
|
465
|
+
...loggerContext,
|
|
466
|
+
duration_ms: Date.now() - startTime,
|
|
467
|
+
error: error instanceof Error ? error.message : String(error)
|
|
420
468
|
});
|
|
421
469
|
throw error;
|
|
422
470
|
}
|
|
423
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* 流式执行 capability,返回带事件协议的流
|
|
474
|
+
* - 优先使用 pluginInstance.runStreamWithEvents
|
|
475
|
+
* - 如果插件不支持,则包装 runStream/run 为 StreamEvent
|
|
476
|
+
*/
|
|
477
|
+
async *executeCallStreamWithEvents(config, actionName, input, contextOverride) {
|
|
478
|
+
const startTime = Date.now();
|
|
479
|
+
const loggerContext = {
|
|
480
|
+
capability_id: config.id,
|
|
481
|
+
plugin_key: config.pluginKey,
|
|
482
|
+
action: actionName
|
|
483
|
+
};
|
|
484
|
+
const chunks = [];
|
|
485
|
+
try {
|
|
486
|
+
const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);
|
|
487
|
+
if (!pluginInstance.hasAction(actionName)) {
|
|
488
|
+
throw new ActionNotFoundError(config.pluginKey, actionName);
|
|
489
|
+
}
|
|
490
|
+
const resolvedParams = config.formValue ? this.templateEngineService.resolve(config.formValue, input) : input;
|
|
491
|
+
const context = this.buildActionContext(contextOverride);
|
|
492
|
+
const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
|
|
493
|
+
this.logger.log("Executing capability (streamWithEvents)", {
|
|
494
|
+
...loggerContext,
|
|
495
|
+
is_stream: isStream,
|
|
496
|
+
input: stringifyForLog(input)
|
|
497
|
+
});
|
|
498
|
+
if (pluginInstance.runStreamWithEvents) {
|
|
499
|
+
for await (const event of pluginInstance.runStreamWithEvents(actionName, context, resolvedParams)) {
|
|
500
|
+
if (event.type === "data") {
|
|
501
|
+
chunks.push(event.data);
|
|
502
|
+
}
|
|
503
|
+
yield event;
|
|
504
|
+
}
|
|
505
|
+
} else {
|
|
506
|
+
if (isStream && pluginInstance.runStream) {
|
|
507
|
+
for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {
|
|
508
|
+
chunks.push(chunk);
|
|
509
|
+
yield {
|
|
510
|
+
type: "data",
|
|
511
|
+
data: chunk
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
} else {
|
|
515
|
+
const result = await pluginInstance.run(actionName, context, resolvedParams);
|
|
516
|
+
chunks.push(result);
|
|
517
|
+
yield {
|
|
518
|
+
type: "data",
|
|
519
|
+
data: result
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
yield {
|
|
523
|
+
type: "done",
|
|
524
|
+
metadata: {
|
|
525
|
+
chunks: chunks.length,
|
|
526
|
+
duration: Date.now() - startTime
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
const aggregatedResult = pluginInstance.aggregate ? pluginInstance.aggregate(actionName, chunks) : chunks;
|
|
531
|
+
this.logger.log("Capability (streamWithEvents) executed successfully", {
|
|
532
|
+
...loggerContext,
|
|
533
|
+
duration_ms: Date.now() - startTime,
|
|
534
|
+
output: stringifyForLog(aggregatedResult)
|
|
535
|
+
});
|
|
536
|
+
} catch (error) {
|
|
537
|
+
this.logger.error("Capability (streamWithEvents) execution failed", {
|
|
538
|
+
...loggerContext,
|
|
539
|
+
duration_ms: Date.now() - startTime,
|
|
540
|
+
error: error instanceof Error ? error.message : String(error)
|
|
541
|
+
});
|
|
542
|
+
yield {
|
|
543
|
+
type: "error",
|
|
544
|
+
error: {
|
|
545
|
+
code: "EXECUTION_ERROR",
|
|
546
|
+
message: error instanceof Error ? error.message : String(error)
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}
|
|
424
551
|
buildActionContext(override) {
|
|
425
552
|
return {
|
|
426
553
|
logger: this.logger,
|
|
427
|
-
|
|
554
|
+
platformHttpClient: this.platformHttpClient,
|
|
428
555
|
userContext: override?.userContext ?? this.getUserContext()
|
|
429
556
|
};
|
|
430
557
|
}
|
|
431
558
|
getUserContext() {
|
|
432
559
|
const ctx = this.requestContextService.getContext();
|
|
433
560
|
return {
|
|
561
|
+
appId: ctx?.appId ?? "",
|
|
434
562
|
userId: ctx?.userId ?? "",
|
|
435
563
|
tenantId: ctx?.tenantId ?? ""
|
|
436
564
|
};
|
|
@@ -467,13 +595,14 @@ function _ts_param2(paramIndex, decorator) {
|
|
|
467
595
|
};
|
|
468
596
|
}
|
|
469
597
|
__name(_ts_param2, "_ts_param");
|
|
470
|
-
var DebugController = class {
|
|
598
|
+
var DebugController = class _DebugController {
|
|
471
599
|
static {
|
|
472
600
|
__name(this, "DebugController");
|
|
473
601
|
}
|
|
474
602
|
capabilityService;
|
|
475
603
|
pluginLoaderService;
|
|
476
604
|
templateEngineService;
|
|
605
|
+
logger = new import_common4.Logger(_DebugController.name);
|
|
477
606
|
constructor(capabilityService, pluginLoaderService, templateEngineService) {
|
|
478
607
|
this.capabilityService = capabilityService;
|
|
479
608
|
this.pluginLoaderService = pluginLoaderService;
|
|
@@ -482,14 +611,15 @@ var DebugController = class {
|
|
|
482
611
|
list() {
|
|
483
612
|
const capabilities = this.capabilityService.listCapabilities();
|
|
484
613
|
return {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
614
|
+
status_code: ErrorCodes.SUCCESS,
|
|
615
|
+
data: {
|
|
616
|
+
capabilities: capabilities.map((c) => ({
|
|
617
|
+
id: c.id,
|
|
618
|
+
name: c.name,
|
|
619
|
+
pluginID: c.pluginKey,
|
|
620
|
+
pluginVersion: c.pluginVersion
|
|
621
|
+
}))
|
|
622
|
+
}
|
|
493
623
|
};
|
|
494
624
|
}
|
|
495
625
|
/**
|
|
@@ -538,102 +668,153 @@ var DebugController = class {
|
|
|
538
668
|
try {
|
|
539
669
|
const result = await this.capabilityService.loadWithConfig(config).call(action, params);
|
|
540
670
|
return {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
671
|
+
status_code: ErrorCodes.SUCCESS,
|
|
672
|
+
data: {
|
|
673
|
+
output: result,
|
|
674
|
+
debug: {
|
|
675
|
+
capabilityConfig: config,
|
|
676
|
+
resolvedParams,
|
|
677
|
+
duration: Date.now() - startTime,
|
|
678
|
+
pluginID: config.pluginKey,
|
|
679
|
+
action
|
|
680
|
+
}
|
|
550
681
|
}
|
|
551
682
|
};
|
|
552
683
|
} catch (error) {
|
|
553
|
-
const duration = Date.now() - startTime;
|
|
554
684
|
if (error instanceof CapabilityNotFoundError) {
|
|
555
685
|
throw new import_common4.HttpException({
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
error: "CAPABILITY_NOT_FOUND",
|
|
559
|
-
debug: {
|
|
560
|
-
duration
|
|
561
|
-
}
|
|
686
|
+
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
687
|
+
error_msg: `Capability not found: ${capabilityId}`
|
|
562
688
|
}, import_common4.HttpStatus.NOT_FOUND);
|
|
563
689
|
}
|
|
564
690
|
if (error instanceof PluginNotFoundError) {
|
|
565
691
|
throw new import_common4.HttpException({
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
error: "PLUGIN_NOT_FOUND",
|
|
569
|
-
debug: {
|
|
570
|
-
duration,
|
|
571
|
-
pluginKey: config.pluginKey,
|
|
572
|
-
action
|
|
573
|
-
}
|
|
692
|
+
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
693
|
+
error_msg: `Plugin not found: ${config.pluginKey}`
|
|
574
694
|
}, import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
575
695
|
}
|
|
576
696
|
if (error instanceof ActionNotFoundError) {
|
|
577
697
|
throw new import_common4.HttpException({
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
error: "ACTION_NOT_FOUND",
|
|
581
|
-
debug: {
|
|
582
|
-
duration,
|
|
583
|
-
pluginKey: config.pluginKey,
|
|
584
|
-
action
|
|
585
|
-
}
|
|
698
|
+
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
699
|
+
error_msg: `Action '${action}' not found in plugin ${config.pluginKey}`
|
|
586
700
|
}, import_common4.HttpStatus.BAD_REQUEST);
|
|
587
701
|
}
|
|
588
702
|
throw new import_common4.HttpException({
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
error: "EXECUTION_ERROR",
|
|
592
|
-
debug: {
|
|
593
|
-
duration,
|
|
594
|
-
pluginKey: config.pluginKey,
|
|
595
|
-
action,
|
|
596
|
-
resolvedParams
|
|
597
|
-
}
|
|
703
|
+
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
704
|
+
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
598
705
|
}, import_common4.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
599
706
|
}
|
|
600
707
|
}
|
|
601
708
|
async debugStream(capabilityId, body, res) {
|
|
602
709
|
const params = body.params ?? {};
|
|
710
|
+
const startTime = Date.now();
|
|
603
711
|
res.setHeader("Content-Type", "text/event-stream");
|
|
604
712
|
res.setHeader("Cache-Control", "no-cache");
|
|
605
713
|
res.setHeader("Connection", "keep-alive");
|
|
606
714
|
try {
|
|
607
715
|
const config = this.getCapabilityConfig(capabilityId, body.capability);
|
|
608
716
|
const action = await this.getActionName(config.pluginKey, body.action);
|
|
717
|
+
const loggerContext = {
|
|
718
|
+
capability_id: config.id,
|
|
719
|
+
plugin_key: config.pluginKey,
|
|
720
|
+
action
|
|
721
|
+
};
|
|
722
|
+
this.logger.log(`Executing capability (stream), input: ${stringifyForLog(params)}`, loggerContext);
|
|
609
723
|
const capability = this.capabilityService.loadWithConfig(config);
|
|
610
|
-
const
|
|
611
|
-
|
|
612
|
-
|
|
724
|
+
const eventStream = capability.callStreamWithEvents(action, params);
|
|
725
|
+
let pendingChunk = null;
|
|
726
|
+
const allChunks = [];
|
|
727
|
+
for await (const event of eventStream) {
|
|
728
|
+
switch (event.type) {
|
|
729
|
+
case "data": {
|
|
730
|
+
allChunks.push(event.data);
|
|
731
|
+
if (pendingChunk !== null) {
|
|
732
|
+
const response = {
|
|
733
|
+
status_code: ErrorCodes.SUCCESS,
|
|
734
|
+
data: {
|
|
735
|
+
type: "content",
|
|
736
|
+
delta: {
|
|
737
|
+
content: pendingChunk
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
742
|
+
|
|
743
|
+
`);
|
|
744
|
+
}
|
|
745
|
+
pendingChunk = event.data;
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
748
|
+
case "done": {
|
|
749
|
+
if (pendingChunk !== null) {
|
|
750
|
+
const response = {
|
|
751
|
+
status_code: ErrorCodes.SUCCESS,
|
|
752
|
+
data: {
|
|
753
|
+
type: "content",
|
|
754
|
+
delta: {
|
|
755
|
+
content: pendingChunk
|
|
756
|
+
},
|
|
757
|
+
finished: true
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
761
|
+
|
|
762
|
+
`);
|
|
763
|
+
}
|
|
764
|
+
this.logger.log(`Capability (stream) executed successfully, duration: ${Date.now() - startTime}ms, chunks: ${allChunks.length}, result: ${stringifyForLog(allChunks)}`, loggerContext);
|
|
765
|
+
res.end();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
case "error": {
|
|
769
|
+
const response = {
|
|
770
|
+
status_code: ErrorCodes.SUCCESS,
|
|
771
|
+
data: {
|
|
772
|
+
type: "error",
|
|
773
|
+
error: {
|
|
774
|
+
code: 0,
|
|
775
|
+
message: event.error.message
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
780
|
+
|
|
781
|
+
`);
|
|
782
|
+
res.end();
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (pendingChunk !== null) {
|
|
788
|
+
const response = {
|
|
789
|
+
status_code: ErrorCodes.SUCCESS,
|
|
790
|
+
data: {
|
|
791
|
+
type: "content",
|
|
792
|
+
delta: {
|
|
793
|
+
content: pendingChunk
|
|
794
|
+
},
|
|
795
|
+
finished: true
|
|
796
|
+
}
|
|
797
|
+
};
|
|
798
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
613
799
|
|
|
614
800
|
`);
|
|
615
801
|
}
|
|
616
|
-
res.
|
|
802
|
+
res.end();
|
|
617
803
|
} catch (error) {
|
|
618
|
-
const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
res.write(`data: ${JSON.stringify({
|
|
631
|
-
error: message,
|
|
632
|
-
code: errorCode
|
|
633
|
-
})}
|
|
804
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
805
|
+
const response = {
|
|
806
|
+
status_code: ErrorCodes.SUCCESS,
|
|
807
|
+
data: {
|
|
808
|
+
type: "error",
|
|
809
|
+
error: {
|
|
810
|
+
code: 0,
|
|
811
|
+
message: errorMsg
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
634
816
|
|
|
635
817
|
`);
|
|
636
|
-
} finally {
|
|
637
818
|
res.end();
|
|
638
819
|
}
|
|
639
820
|
}
|
|
@@ -642,7 +823,7 @@ _ts_decorate4([
|
|
|
642
823
|
(0, import_common4.Get)("list"),
|
|
643
824
|
_ts_metadata2("design:type", Function),
|
|
644
825
|
_ts_metadata2("design:paramtypes", []),
|
|
645
|
-
_ts_metadata2("design:returntype", typeof
|
|
826
|
+
_ts_metadata2("design:returntype", typeof SuccessResponse === "undefined" ? Object : SuccessResponse)
|
|
646
827
|
], DebugController.prototype, "list", null);
|
|
647
828
|
_ts_decorate4([
|
|
648
829
|
(0, import_common4.Post)("debug/:capability_id"),
|
|
@@ -697,95 +878,170 @@ function _ts_param3(paramIndex, decorator) {
|
|
|
697
878
|
};
|
|
698
879
|
}
|
|
699
880
|
__name(_ts_param3, "_ts_param");
|
|
700
|
-
var WebhookController = class {
|
|
881
|
+
var WebhookController = class _WebhookController {
|
|
701
882
|
static {
|
|
702
883
|
__name(this, "WebhookController");
|
|
703
884
|
}
|
|
704
885
|
capabilityService;
|
|
886
|
+
logger = new import_common5.Logger(_WebhookController.name);
|
|
705
887
|
constructor(capabilityService) {
|
|
706
888
|
this.capabilityService = capabilityService;
|
|
707
889
|
}
|
|
708
890
|
list() {
|
|
709
891
|
const capabilities = this.capabilityService.listCapabilities();
|
|
710
892
|
return {
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
}
|
|
893
|
+
status_code: ErrorCodes.SUCCESS,
|
|
894
|
+
data: {
|
|
895
|
+
capabilities: capabilities.map((c) => ({
|
|
896
|
+
id: c.id,
|
|
897
|
+
name: c.name,
|
|
898
|
+
pluginID: c.pluginKey,
|
|
899
|
+
pluginVersion: c.pluginVersion
|
|
900
|
+
}))
|
|
901
|
+
}
|
|
720
902
|
};
|
|
721
903
|
}
|
|
722
904
|
async execute(capabilityId, body) {
|
|
723
905
|
try {
|
|
724
906
|
const result = await this.capabilityService.load(capabilityId).call(body.action, body.params);
|
|
725
907
|
return {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
908
|
+
status_code: ErrorCodes.SUCCESS,
|
|
909
|
+
data: {
|
|
910
|
+
output: result
|
|
911
|
+
}
|
|
729
912
|
};
|
|
730
913
|
} catch (error) {
|
|
731
914
|
if (error instanceof CapabilityNotFoundError) {
|
|
732
915
|
throw new import_common5.HttpException({
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
error: "CAPABILITY_NOT_FOUND"
|
|
916
|
+
status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
|
|
917
|
+
error_msg: `Capability not found: ${capabilityId}`
|
|
736
918
|
}, import_common5.HttpStatus.NOT_FOUND);
|
|
737
919
|
}
|
|
738
920
|
if (error instanceof PluginNotFoundError) {
|
|
739
921
|
throw new import_common5.HttpException({
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
error: "PLUGIN_NOT_FOUND"
|
|
922
|
+
status_code: ErrorCodes.PLUGIN_NOT_FOUND,
|
|
923
|
+
error_msg: `Plugin not found`
|
|
743
924
|
}, import_common5.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
744
925
|
}
|
|
745
926
|
if (error instanceof ActionNotFoundError) {
|
|
746
927
|
throw new import_common5.HttpException({
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
error: "ACTION_NOT_FOUND"
|
|
928
|
+
status_code: ErrorCodes.ACTION_NOT_FOUND,
|
|
929
|
+
error_msg: `Action '${body.action}' not found`
|
|
750
930
|
}, import_common5.HttpStatus.BAD_REQUEST);
|
|
751
931
|
}
|
|
752
932
|
throw new import_common5.HttpException({
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
error: "EXECUTION_ERROR"
|
|
933
|
+
status_code: ErrorCodes.EXECUTION_ERROR,
|
|
934
|
+
error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
756
935
|
}, import_common5.HttpStatus.INTERNAL_SERVER_ERROR);
|
|
757
936
|
}
|
|
758
937
|
}
|
|
759
938
|
async executeStream(capabilityId, body, res) {
|
|
939
|
+
const startTime = Date.now();
|
|
940
|
+
const loggerContext = {
|
|
941
|
+
capability_id: capabilityId,
|
|
942
|
+
action: body.action
|
|
943
|
+
};
|
|
760
944
|
res.setHeader("Content-Type", "text/event-stream");
|
|
761
945
|
res.setHeader("Cache-Control", "no-cache");
|
|
762
946
|
res.setHeader("Connection", "keep-alive");
|
|
763
947
|
try {
|
|
948
|
+
this.logger.log(`Executing capability (stream), input: ${stringifyForLog(body.params)}`, loggerContext);
|
|
764
949
|
const capability = this.capabilityService.load(capabilityId);
|
|
765
|
-
const
|
|
766
|
-
|
|
767
|
-
|
|
950
|
+
const eventStream = capability.callStreamWithEvents(body.action, body.params);
|
|
951
|
+
let pendingChunk = null;
|
|
952
|
+
const allChunks = [];
|
|
953
|
+
for await (const event of eventStream) {
|
|
954
|
+
switch (event.type) {
|
|
955
|
+
case "data": {
|
|
956
|
+
allChunks.push(event.data);
|
|
957
|
+
if (pendingChunk !== null) {
|
|
958
|
+
const response = {
|
|
959
|
+
status_code: ErrorCodes.SUCCESS,
|
|
960
|
+
data: {
|
|
961
|
+
type: "content",
|
|
962
|
+
delta: {
|
|
963
|
+
content: pendingChunk
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
968
|
+
|
|
969
|
+
`);
|
|
970
|
+
}
|
|
971
|
+
pendingChunk = event.data;
|
|
972
|
+
break;
|
|
973
|
+
}
|
|
974
|
+
case "done": {
|
|
975
|
+
if (pendingChunk !== null) {
|
|
976
|
+
const response = {
|
|
977
|
+
status_code: ErrorCodes.SUCCESS,
|
|
978
|
+
data: {
|
|
979
|
+
type: "content",
|
|
980
|
+
delta: {
|
|
981
|
+
content: pendingChunk
|
|
982
|
+
},
|
|
983
|
+
finished: true
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
768
987
|
|
|
769
988
|
`);
|
|
989
|
+
}
|
|
990
|
+
this.logger.log(`Capability (stream) executed successfully, duration: ${Date.now() - startTime}ms, chunks: ${allChunks.length}, result: ${stringifyForLog(allChunks)}`, loggerContext);
|
|
991
|
+
res.end();
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
case "error": {
|
|
995
|
+
const response = {
|
|
996
|
+
status_code: ErrorCodes.SUCCESS,
|
|
997
|
+
data: {
|
|
998
|
+
type: "error",
|
|
999
|
+
error: {
|
|
1000
|
+
code: 0,
|
|
1001
|
+
message: event.error.message
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
};
|
|
1005
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
1006
|
+
|
|
1007
|
+
`);
|
|
1008
|
+
res.end();
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
770
1012
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
1013
|
+
if (pendingChunk !== null) {
|
|
1014
|
+
const response = {
|
|
1015
|
+
status_code: ErrorCodes.SUCCESS,
|
|
1016
|
+
data: {
|
|
1017
|
+
type: "content",
|
|
1018
|
+
delta: {
|
|
1019
|
+
content: pendingChunk
|
|
1020
|
+
},
|
|
1021
|
+
finished: true
|
|
1022
|
+
}
|
|
1023
|
+
};
|
|
1024
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
1025
|
+
|
|
1026
|
+
`);
|
|
781
1027
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1028
|
+
this.logger.log(`Capability (stream) executed successfully, duration: ${Date.now() - startTime}ms, chunks: ${allChunks.length}, result: ${stringifyForLog(allChunks)}`, loggerContext);
|
|
1029
|
+
res.end();
|
|
1030
|
+
} catch (error) {
|
|
1031
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
1032
|
+
const response = {
|
|
1033
|
+
status_code: ErrorCodes.SUCCESS,
|
|
1034
|
+
data: {
|
|
1035
|
+
type: "error",
|
|
1036
|
+
error: {
|
|
1037
|
+
code: 0,
|
|
1038
|
+
message: errorMsg
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
res.write(`data: ${JSON.stringify(response)}
|
|
786
1043
|
|
|
787
1044
|
`);
|
|
788
|
-
} finally {
|
|
789
1045
|
res.end();
|
|
790
1046
|
}
|
|
791
1047
|
}
|
|
@@ -794,7 +1050,7 @@ _ts_decorate5([
|
|
|
794
1050
|
(0, import_common5.Get)("list"),
|
|
795
1051
|
_ts_metadata3("design:type", Function),
|
|
796
1052
|
_ts_metadata3("design:paramtypes", []),
|
|
797
|
-
_ts_metadata3("design:returntype", typeof
|
|
1053
|
+
_ts_metadata3("design:returntype", typeof SuccessResponse === "undefined" ? Object : SuccessResponse)
|
|
798
1054
|
], WebhookController.prototype, "list", null);
|
|
799
1055
|
_ts_decorate5([
|
|
800
1056
|
(0, import_common5.Post)(":capability_id"),
|
|
@@ -857,6 +1113,9 @@ var CapabilityModule = class _CapabilityModule {
|
|
|
857
1113
|
static forRoot(options) {
|
|
858
1114
|
return {
|
|
859
1115
|
module: _CapabilityModule,
|
|
1116
|
+
imports: [
|
|
1117
|
+
import_nestjs_common2.CommonModule
|
|
1118
|
+
],
|
|
860
1119
|
controllers: getControllers(),
|
|
861
1120
|
providers: [
|
|
862
1121
|
{
|
|
@@ -891,6 +1150,9 @@ var CapabilityModule = class _CapabilityModule {
|
|
|
891
1150
|
};
|
|
892
1151
|
CapabilityModule = _ts_decorate6([
|
|
893
1152
|
(0, import_common6.Module)({
|
|
1153
|
+
imports: [
|
|
1154
|
+
import_nestjs_common2.CommonModule
|
|
1155
|
+
],
|
|
894
1156
|
controllers: getControllers(),
|
|
895
1157
|
providers: [
|
|
896
1158
|
CapabilityService,
|
|
@@ -909,6 +1171,7 @@ CapabilityModule = _ts_decorate6([
|
|
|
909
1171
|
CapabilityNotFoundError,
|
|
910
1172
|
CapabilityService,
|
|
911
1173
|
DebugController,
|
|
1174
|
+
ErrorCodes,
|
|
912
1175
|
PluginLoadError,
|
|
913
1176
|
PluginLoaderService,
|
|
914
1177
|
PluginNotFoundError,
|