@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 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
- httpClient;
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, httpClient, pluginLoaderService, templateEngineService) {
288
+ constructor(requestContextService, platformHttpClient, pluginLoaderService, templateEngineService) {
250
289
  this.requestContextService = requestContextService;
251
- this.httpClient = httpClient;
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
- message: "Executing capability",
346
- capabilityId: config.id,
347
- action: actionName,
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
- message: "Capability executed successfully",
363
- capabilityId: config.id,
364
- action: actionName,
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
- message: "Capability execution failed",
371
- capabilityId: config.id,
372
- action: actionName,
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
- message: "Executing capability (stream)",
396
- capabilityId: config.id,
397
- action: actionName,
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
- yield* pluginInstance.runStream(actionName, context, resolvedParams);
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
- this.logger.log({
408
- message: "Capability stream completed",
409
- capabilityId: config.id,
410
- action: actionName,
411
- duration: Date.now() - startTime
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
- message: "Capability stream execution failed",
416
- capabilityId: config.id,
417
- action: actionName,
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
- httpClient: this.httpClient,
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
- code: 0,
486
- message: "success",
487
- data: capabilities.map((c) => ({
488
- id: c.id,
489
- name: c.name,
490
- pluginKey: c.pluginKey,
491
- pluginVersion: c.pluginVersion
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
- code: 0,
542
- message: "success",
543
- data: result,
544
- debug: {
545
- capabilityConfig: config,
546
- resolvedParams,
547
- duration: Date.now() - startTime,
548
- pluginKey: config.pluginKey,
549
- action
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
- code: 1,
557
- message: error.message,
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
- code: 1,
567
- message: error.message,
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
- code: 1,
579
- message: error.message,
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
- code: 1,
590
- message: error instanceof Error ? error.message : String(error),
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 stream = capability.callStream(action, params);
611
- for await (const chunk of stream) {
612
- res.write(`data: ${JSON.stringify(chunk)}
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.write("data: [DONE]\n\n");
802
+ res.end();
617
803
  } catch (error) {
618
- const message = error instanceof Error ? error.message : String(error);
619
- let errorCode = "EXECUTION_ERROR";
620
- if (error instanceof CapabilityNotFoundError) {
621
- errorCode = "CAPABILITY_NOT_FOUND";
622
- } else if (error instanceof PluginNotFoundError) {
623
- errorCode = "PLUGIN_NOT_FOUND";
624
- } else if (error instanceof ActionNotFoundError) {
625
- errorCode = "ACTION_NOT_FOUND";
626
- } else if (error instanceof import_common4.HttpException) {
627
- const response = error.getResponse();
628
- errorCode = response.error ?? "EXECUTION_ERROR";
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 ListResponse === "undefined" ? Object : ListResponse)
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
- code: 0,
712
- message: "success",
713
- data: capabilities.map((c) => ({
714
- id: c.id,
715
- name: c.name,
716
- description: c.description,
717
- pluginKey: c.pluginKey,
718
- pluginVersion: c.pluginVersion
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
- code: 0,
727
- message: "success",
728
- data: result
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
- code: 1,
734
- message: error.message,
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
- code: 1,
741
- message: error.message,
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
- code: 1,
748
- message: error.message,
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
- code: 1,
754
- message: error instanceof Error ? error.message : String(error),
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 stream = capability.callStream(body.action, body.params);
766
- for await (const chunk of stream) {
767
- res.write(`data: ${JSON.stringify(chunk)}
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
- res.write("data: [DONE]\n\n");
772
- } catch (error) {
773
- const message = error instanceof Error ? error.message : String(error);
774
- let errorCode = "EXECUTION_ERROR";
775
- if (error instanceof CapabilityNotFoundError) {
776
- errorCode = "CAPABILITY_NOT_FOUND";
777
- } else if (error instanceof PluginNotFoundError) {
778
- errorCode = "PLUGIN_NOT_FOUND";
779
- } else if (error instanceof ActionNotFoundError) {
780
- errorCode = "ACTION_NOT_FOUND";
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
- res.write(`data: ${JSON.stringify({
783
- error: message,
784
- code: errorCode
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 ListResponse === "undefined" ? Object : ListResponse)
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,