@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.js CHANGED
@@ -7,6 +7,22 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
7
7
  throw Error('Dynamic require of "' + x + '" is not supported');
8
8
  });
9
9
 
10
+ // src/interfaces/error-codes.ts
11
+ var ErrorCodes = {
12
+ /** 成功 */
13
+ SUCCESS: "0",
14
+ /** 能力不存在 */
15
+ CAPABILITY_NOT_FOUND: "k_ec_cap_001",
16
+ /** 插件不存在 */
17
+ PLUGIN_NOT_FOUND: "k_ec_cap_002",
18
+ /** Action 不存在 */
19
+ ACTION_NOT_FOUND: "k_ec_cap_003",
20
+ /** 参数验证失败 */
21
+ PARAMS_VALIDATION_ERROR: "k_ec_cap_004",
22
+ /** 执行失败 */
23
+ EXECUTION_ERROR: "k_ec_cap_005"
24
+ };
25
+
10
26
  // src/services/template-engine.service.ts
11
27
  import { Injectable } from "@nestjs/common";
12
28
  function _ts_decorate(decorators, target, key, desc) {
@@ -163,6 +179,28 @@ import { Injectable as Injectable3, Logger as Logger2, Inject } from "@nestjs/co
163
179
  import { RequestContextService, PLATFORM_HTTP_CLIENT } from "@lark-apaas/nestjs-common";
164
180
  import * as fs from "fs";
165
181
  import * as path from "path";
182
+
183
+ // src/utils/log-utils.ts
184
+ var DEFAULT_MAX_LENGTH = 1e3;
185
+ function truncateString(str, maxLength) {
186
+ if (str.length <= maxLength) {
187
+ return str;
188
+ }
189
+ return str.slice(0, maxLength) + `... [truncated, total ${str.length} chars]`;
190
+ }
191
+ __name(truncateString, "truncateString");
192
+ function stringifyForLog(value, maxLength = DEFAULT_MAX_LENGTH) {
193
+ try {
194
+ const str = JSON.stringify(value, null, 2);
195
+ return truncateString(str, maxLength);
196
+ } catch {
197
+ const str = String(value);
198
+ return truncateString(str, maxLength);
199
+ }
200
+ }
201
+ __name(stringifyForLog, "stringifyForLog");
202
+
203
+ // src/services/capability.service.ts
166
204
  function _ts_decorate3(decorators, target, key, desc) {
167
205
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
168
206
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -203,15 +241,15 @@ var CapabilityService = class _CapabilityService {
203
241
  __name(this, "CapabilityService");
204
242
  }
205
243
  requestContextService;
206
- httpClient;
244
+ platformHttpClient;
207
245
  pluginLoaderService;
208
246
  templateEngineService;
209
247
  logger = new Logger2(_CapabilityService.name);
210
248
  capabilities = /* @__PURE__ */ new Map();
211
249
  capabilitiesDir;
212
- constructor(requestContextService, httpClient, pluginLoaderService, templateEngineService) {
250
+ constructor(requestContextService, platformHttpClient, pluginLoaderService, templateEngineService) {
213
251
  this.requestContextService = requestContextService;
214
- this.httpClient = httpClient;
252
+ this.platformHttpClient = platformHttpClient;
215
253
  this.pluginLoaderService = pluginLoaderService;
216
254
  this.templateEngineService = templateEngineService;
217
255
  this.capabilitiesDir = path.join(process.cwd(), "server/capabilities");
@@ -274,6 +312,9 @@ var CapabilityService = class _CapabilityService {
274
312
  callStream: /* @__PURE__ */ __name((actionName, input, contextOverride) => {
275
313
  return this.executeCallStream(config, actionName, input, contextOverride);
276
314
  }, "callStream"),
315
+ callStreamWithEvents: /* @__PURE__ */ __name((actionName, input, contextOverride) => {
316
+ return this.executeCallStreamWithEvents(config, actionName, input, contextOverride);
317
+ }, "callStreamWithEvents"),
277
318
  isStream: /* @__PURE__ */ __name(async (actionName) => {
278
319
  return this.checkIsStream(config, actionName);
279
320
  }, "isStream")
@@ -296,20 +337,23 @@ var CapabilityService = class _CapabilityService {
296
337
  */
297
338
  async executeCall(config, actionName, input, contextOverride) {
298
339
  const startTime = Date.now();
340
+ const loggerContext = {
341
+ capability_id: config.id,
342
+ plugin_key: config.pluginKey,
343
+ action: actionName
344
+ };
299
345
  try {
300
346
  const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);
301
347
  if (!pluginInstance.hasAction(actionName)) {
302
348
  throw new ActionNotFoundError(config.pluginKey, actionName);
303
349
  }
304
- const resolvedParams = this.templateEngineService.resolve(config.formValue, input);
350
+ const resolvedParams = config.formValue ? this.templateEngineService.resolve(config.formValue, input) : input;
305
351
  const context = this.buildActionContext(contextOverride);
306
352
  const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
307
- this.logger.log({
308
- message: "Executing capability",
309
- capabilityId: config.id,
310
- action: actionName,
311
- pluginKey: config.pluginKey,
312
- isStream
353
+ this.logger.log("Executing capability (call)", {
354
+ ...loggerContext,
355
+ is_stream: isStream,
356
+ input: stringifyForLog(input)
313
357
  });
314
358
  let result;
315
359
  if (isStream && pluginInstance.runStream) {
@@ -321,20 +365,17 @@ var CapabilityService = class _CapabilityService {
321
365
  } else {
322
366
  result = await pluginInstance.run(actionName, context, resolvedParams);
323
367
  }
324
- this.logger.log({
325
- message: "Capability executed successfully",
326
- capabilityId: config.id,
327
- action: actionName,
328
- duration: Date.now() - startTime
368
+ this.logger.log("Capability (call) executed successfully", {
369
+ ...loggerContext,
370
+ duration_ms: Date.now() - startTime,
371
+ output: stringifyForLog(result)
329
372
  });
330
373
  return result;
331
374
  } catch (error) {
332
- this.logger.error({
333
- message: "Capability execution failed",
334
- capabilityId: config.id,
335
- action: actionName,
336
- error: error instanceof Error ? error.message : String(error),
337
- duration: Date.now() - startTime
375
+ this.logger.error("Capability (call) execution failed", {
376
+ ...loggerContext,
377
+ duration_ms: Date.now() - startTime,
378
+ error: error instanceof Error ? error.message : String(error)
338
379
  });
339
380
  throw error;
340
381
  }
@@ -346,54 +387,140 @@ var CapabilityService = class _CapabilityService {
346
387
  */
347
388
  async *executeCallStream(config, actionName, input, contextOverride) {
348
389
  const startTime = Date.now();
390
+ const loggerContext = {
391
+ capability_id: config.id,
392
+ plugin_key: config.pluginKey,
393
+ action: actionName
394
+ };
395
+ const chunks = [];
349
396
  try {
350
397
  const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);
351
398
  if (!pluginInstance.hasAction(actionName)) {
352
399
  throw new ActionNotFoundError(config.pluginKey, actionName);
353
400
  }
354
- const resolvedParams = this.templateEngineService.resolve(config.formValue, input);
401
+ const resolvedParams = config.formValue ? this.templateEngineService.resolve(config.formValue, input) : input;
355
402
  const context = this.buildActionContext(contextOverride);
356
403
  const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
357
- this.logger.log({
358
- message: "Executing capability (stream)",
359
- capabilityId: config.id,
360
- action: actionName,
361
- pluginKey: config.pluginKey,
362
- isStream
404
+ this.logger.log("Executing capability (stream)", {
405
+ ...loggerContext,
406
+ is_stream: isStream,
407
+ input: stringifyForLog(input)
363
408
  });
364
409
  if (isStream && pluginInstance.runStream) {
365
- yield* pluginInstance.runStream(actionName, context, resolvedParams);
410
+ for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {
411
+ chunks.push(chunk);
412
+ yield chunk;
413
+ }
366
414
  } else {
367
415
  const result = await pluginInstance.run(actionName, context, resolvedParams);
416
+ chunks.push(result);
368
417
  yield result;
369
418
  }
370
- this.logger.log({
371
- message: "Capability stream completed",
372
- capabilityId: config.id,
373
- action: actionName,
374
- duration: Date.now() - startTime
419
+ const aggregatedResult = pluginInstance.aggregate ? pluginInstance.aggregate(actionName, chunks) : chunks;
420
+ this.logger.log("Capability (stream) executed successfully", {
421
+ ...loggerContext,
422
+ duration_ms: Date.now() - startTime,
423
+ output: stringifyForLog(aggregatedResult)
375
424
  });
376
425
  } catch (error) {
377
- this.logger.error({
378
- message: "Capability stream execution failed",
379
- capabilityId: config.id,
380
- action: actionName,
381
- error: error instanceof Error ? error.message : String(error),
382
- duration: Date.now() - startTime
426
+ this.logger.error("Capability (stream) execution failed", {
427
+ ...loggerContext,
428
+ duration_ms: Date.now() - startTime,
429
+ error: error instanceof Error ? error.message : String(error)
383
430
  });
384
431
  throw error;
385
432
  }
386
433
  }
434
+ /**
435
+ * 流式执行 capability,返回带事件协议的流
436
+ * - 优先使用 pluginInstance.runStreamWithEvents
437
+ * - 如果插件不支持,则包装 runStream/run 为 StreamEvent
438
+ */
439
+ async *executeCallStreamWithEvents(config, actionName, input, contextOverride) {
440
+ const startTime = Date.now();
441
+ const loggerContext = {
442
+ capability_id: config.id,
443
+ plugin_key: config.pluginKey,
444
+ action: actionName
445
+ };
446
+ const chunks = [];
447
+ try {
448
+ const pluginInstance = await this.pluginLoaderService.loadPlugin(config.pluginKey);
449
+ if (!pluginInstance.hasAction(actionName)) {
450
+ throw new ActionNotFoundError(config.pluginKey, actionName);
451
+ }
452
+ const resolvedParams = config.formValue ? this.templateEngineService.resolve(config.formValue, input) : input;
453
+ const context = this.buildActionContext(contextOverride);
454
+ const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
455
+ this.logger.log("Executing capability (streamWithEvents)", {
456
+ ...loggerContext,
457
+ is_stream: isStream,
458
+ input: stringifyForLog(input)
459
+ });
460
+ if (pluginInstance.runStreamWithEvents) {
461
+ for await (const event of pluginInstance.runStreamWithEvents(actionName, context, resolvedParams)) {
462
+ if (event.type === "data") {
463
+ chunks.push(event.data);
464
+ }
465
+ yield event;
466
+ }
467
+ } else {
468
+ if (isStream && pluginInstance.runStream) {
469
+ for await (const chunk of pluginInstance.runStream(actionName, context, resolvedParams)) {
470
+ chunks.push(chunk);
471
+ yield {
472
+ type: "data",
473
+ data: chunk
474
+ };
475
+ }
476
+ } else {
477
+ const result = await pluginInstance.run(actionName, context, resolvedParams);
478
+ chunks.push(result);
479
+ yield {
480
+ type: "data",
481
+ data: result
482
+ };
483
+ }
484
+ yield {
485
+ type: "done",
486
+ metadata: {
487
+ chunks: chunks.length,
488
+ duration: Date.now() - startTime
489
+ }
490
+ };
491
+ }
492
+ const aggregatedResult = pluginInstance.aggregate ? pluginInstance.aggregate(actionName, chunks) : chunks;
493
+ this.logger.log("Capability (streamWithEvents) executed successfully", {
494
+ ...loggerContext,
495
+ duration_ms: Date.now() - startTime,
496
+ output: stringifyForLog(aggregatedResult)
497
+ });
498
+ } catch (error) {
499
+ this.logger.error("Capability (streamWithEvents) execution failed", {
500
+ ...loggerContext,
501
+ duration_ms: Date.now() - startTime,
502
+ error: error instanceof Error ? error.message : String(error)
503
+ });
504
+ yield {
505
+ type: "error",
506
+ error: {
507
+ code: "EXECUTION_ERROR",
508
+ message: error instanceof Error ? error.message : String(error)
509
+ }
510
+ };
511
+ }
512
+ }
387
513
  buildActionContext(override) {
388
514
  return {
389
515
  logger: this.logger,
390
- httpClient: this.httpClient,
516
+ platformHttpClient: this.platformHttpClient,
391
517
  userContext: override?.userContext ?? this.getUserContext()
392
518
  };
393
519
  }
394
520
  getUserContext() {
395
521
  const ctx = this.requestContextService.getContext();
396
522
  return {
523
+ appId: ctx?.appId ?? "",
397
524
  userId: ctx?.userId ?? "",
398
525
  tenantId: ctx?.tenantId ?? ""
399
526
  };
@@ -412,7 +539,7 @@ CapabilityService = _ts_decorate3([
412
539
  ], CapabilityService);
413
540
 
414
541
  // src/controllers/debug.controller.ts
415
- import { Controller, Post, Get, Param, Body, Res, HttpException, HttpStatus } from "@nestjs/common";
542
+ import { Controller, Post, Get, Param, Body, Res, HttpException, HttpStatus, Logger as Logger3 } from "@nestjs/common";
416
543
  function _ts_decorate4(decorators, target, key, desc) {
417
544
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
418
545
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -430,13 +557,14 @@ function _ts_param2(paramIndex, decorator) {
430
557
  };
431
558
  }
432
559
  __name(_ts_param2, "_ts_param");
433
- var DebugController = class {
560
+ var DebugController = class _DebugController {
434
561
  static {
435
562
  __name(this, "DebugController");
436
563
  }
437
564
  capabilityService;
438
565
  pluginLoaderService;
439
566
  templateEngineService;
567
+ logger = new Logger3(_DebugController.name);
440
568
  constructor(capabilityService, pluginLoaderService, templateEngineService) {
441
569
  this.capabilityService = capabilityService;
442
570
  this.pluginLoaderService = pluginLoaderService;
@@ -445,14 +573,15 @@ var DebugController = class {
445
573
  list() {
446
574
  const capabilities = this.capabilityService.listCapabilities();
447
575
  return {
448
- code: 0,
449
- message: "success",
450
- data: capabilities.map((c) => ({
451
- id: c.id,
452
- name: c.name,
453
- pluginKey: c.pluginKey,
454
- pluginVersion: c.pluginVersion
455
- }))
576
+ status_code: ErrorCodes.SUCCESS,
577
+ data: {
578
+ capabilities: capabilities.map((c) => ({
579
+ id: c.id,
580
+ name: c.name,
581
+ pluginID: c.pluginKey,
582
+ pluginVersion: c.pluginVersion
583
+ }))
584
+ }
456
585
  };
457
586
  }
458
587
  /**
@@ -501,102 +630,153 @@ var DebugController = class {
501
630
  try {
502
631
  const result = await this.capabilityService.loadWithConfig(config).call(action, params);
503
632
  return {
504
- code: 0,
505
- message: "success",
506
- data: result,
507
- debug: {
508
- capabilityConfig: config,
509
- resolvedParams,
510
- duration: Date.now() - startTime,
511
- pluginKey: config.pluginKey,
512
- action
633
+ status_code: ErrorCodes.SUCCESS,
634
+ data: {
635
+ output: result,
636
+ debug: {
637
+ capabilityConfig: config,
638
+ resolvedParams,
639
+ duration: Date.now() - startTime,
640
+ pluginID: config.pluginKey,
641
+ action
642
+ }
513
643
  }
514
644
  };
515
645
  } catch (error) {
516
- const duration = Date.now() - startTime;
517
646
  if (error instanceof CapabilityNotFoundError) {
518
647
  throw new HttpException({
519
- code: 1,
520
- message: error.message,
521
- error: "CAPABILITY_NOT_FOUND",
522
- debug: {
523
- duration
524
- }
648
+ status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
649
+ error_msg: `Capability not found: ${capabilityId}`
525
650
  }, HttpStatus.NOT_FOUND);
526
651
  }
527
652
  if (error instanceof PluginNotFoundError) {
528
653
  throw new HttpException({
529
- code: 1,
530
- message: error.message,
531
- error: "PLUGIN_NOT_FOUND",
532
- debug: {
533
- duration,
534
- pluginKey: config.pluginKey,
535
- action
536
- }
654
+ status_code: ErrorCodes.PLUGIN_NOT_FOUND,
655
+ error_msg: `Plugin not found: ${config.pluginKey}`
537
656
  }, HttpStatus.INTERNAL_SERVER_ERROR);
538
657
  }
539
658
  if (error instanceof ActionNotFoundError) {
540
659
  throw new HttpException({
541
- code: 1,
542
- message: error.message,
543
- error: "ACTION_NOT_FOUND",
544
- debug: {
545
- duration,
546
- pluginKey: config.pluginKey,
547
- action
548
- }
660
+ status_code: ErrorCodes.ACTION_NOT_FOUND,
661
+ error_msg: `Action '${action}' not found in plugin ${config.pluginKey}`
549
662
  }, HttpStatus.BAD_REQUEST);
550
663
  }
551
664
  throw new HttpException({
552
- code: 1,
553
- message: error instanceof Error ? error.message : String(error),
554
- error: "EXECUTION_ERROR",
555
- debug: {
556
- duration,
557
- pluginKey: config.pluginKey,
558
- action,
559
- resolvedParams
560
- }
665
+ status_code: ErrorCodes.EXECUTION_ERROR,
666
+ error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
561
667
  }, HttpStatus.INTERNAL_SERVER_ERROR);
562
668
  }
563
669
  }
564
670
  async debugStream(capabilityId, body, res) {
565
671
  const params = body.params ?? {};
672
+ const startTime = Date.now();
566
673
  res.setHeader("Content-Type", "text/event-stream");
567
674
  res.setHeader("Cache-Control", "no-cache");
568
675
  res.setHeader("Connection", "keep-alive");
569
676
  try {
570
677
  const config = this.getCapabilityConfig(capabilityId, body.capability);
571
678
  const action = await this.getActionName(config.pluginKey, body.action);
679
+ const loggerContext = {
680
+ capability_id: config.id,
681
+ plugin_key: config.pluginKey,
682
+ action
683
+ };
684
+ this.logger.log(`Executing capability (stream), input: ${stringifyForLog(params)}`, loggerContext);
572
685
  const capability = this.capabilityService.loadWithConfig(config);
573
- const stream = capability.callStream(action, params);
574
- for await (const chunk of stream) {
575
- res.write(`data: ${JSON.stringify(chunk)}
686
+ const eventStream = capability.callStreamWithEvents(action, params);
687
+ let pendingChunk = null;
688
+ const allChunks = [];
689
+ for await (const event of eventStream) {
690
+ switch (event.type) {
691
+ case "data": {
692
+ allChunks.push(event.data);
693
+ if (pendingChunk !== null) {
694
+ const response = {
695
+ status_code: ErrorCodes.SUCCESS,
696
+ data: {
697
+ type: "content",
698
+ delta: {
699
+ content: pendingChunk
700
+ }
701
+ }
702
+ };
703
+ res.write(`data: ${JSON.stringify(response)}
704
+
705
+ `);
706
+ }
707
+ pendingChunk = event.data;
708
+ break;
709
+ }
710
+ case "done": {
711
+ if (pendingChunk !== null) {
712
+ const response = {
713
+ status_code: ErrorCodes.SUCCESS,
714
+ data: {
715
+ type: "content",
716
+ delta: {
717
+ content: pendingChunk
718
+ },
719
+ finished: true
720
+ }
721
+ };
722
+ res.write(`data: ${JSON.stringify(response)}
723
+
724
+ `);
725
+ }
726
+ this.logger.log(`Capability (stream) executed successfully, duration: ${Date.now() - startTime}ms, chunks: ${allChunks.length}, result: ${stringifyForLog(allChunks)}`, loggerContext);
727
+ res.end();
728
+ return;
729
+ }
730
+ case "error": {
731
+ const response = {
732
+ status_code: ErrorCodes.SUCCESS,
733
+ data: {
734
+ type: "error",
735
+ error: {
736
+ code: 0,
737
+ message: event.error.message
738
+ }
739
+ }
740
+ };
741
+ res.write(`data: ${JSON.stringify(response)}
742
+
743
+ `);
744
+ res.end();
745
+ return;
746
+ }
747
+ }
748
+ }
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)}
576
761
 
577
762
  `);
578
763
  }
579
- res.write("data: [DONE]\n\n");
764
+ res.end();
580
765
  } catch (error) {
581
- const message = error instanceof Error ? error.message : String(error);
582
- let errorCode = "EXECUTION_ERROR";
583
- if (error instanceof CapabilityNotFoundError) {
584
- errorCode = "CAPABILITY_NOT_FOUND";
585
- } else if (error instanceof PluginNotFoundError) {
586
- errorCode = "PLUGIN_NOT_FOUND";
587
- } else if (error instanceof ActionNotFoundError) {
588
- errorCode = "ACTION_NOT_FOUND";
589
- } else if (error instanceof HttpException) {
590
- const response = error.getResponse();
591
- errorCode = response.error ?? "EXECUTION_ERROR";
592
- }
593
- res.write(`data: ${JSON.stringify({
594
- error: message,
595
- code: errorCode
596
- })}
766
+ const errorMsg = error instanceof Error ? error.message : String(error);
767
+ const response = {
768
+ status_code: ErrorCodes.SUCCESS,
769
+ data: {
770
+ type: "error",
771
+ error: {
772
+ code: 0,
773
+ message: errorMsg
774
+ }
775
+ }
776
+ };
777
+ res.write(`data: ${JSON.stringify(response)}
597
778
 
598
779
  `);
599
- } finally {
600
780
  res.end();
601
781
  }
602
782
  }
@@ -605,7 +785,7 @@ _ts_decorate4([
605
785
  Get("list"),
606
786
  _ts_metadata2("design:type", Function),
607
787
  _ts_metadata2("design:paramtypes", []),
608
- _ts_metadata2("design:returntype", typeof ListResponse === "undefined" ? Object : ListResponse)
788
+ _ts_metadata2("design:returntype", typeof SuccessResponse === "undefined" ? Object : SuccessResponse)
609
789
  ], DebugController.prototype, "list", null);
610
790
  _ts_decorate4([
611
791
  Post("debug/:capability_id"),
@@ -642,7 +822,7 @@ DebugController = _ts_decorate4([
642
822
  ], DebugController);
643
823
 
644
824
  // src/controllers/webhook.controller.ts
645
- import { Controller as Controller2, Get as Get2, Post as Post2, Param as Param2, Body as Body2, Res as Res2, HttpException as HttpException2, HttpStatus as HttpStatus2 } from "@nestjs/common";
825
+ import { Controller as Controller2, Get as Get2, Post as Post2, Param as Param2, Body as Body2, Res as Res2, HttpException as HttpException2, HttpStatus as HttpStatus2, Logger as Logger4 } from "@nestjs/common";
646
826
  function _ts_decorate5(decorators, target, key, desc) {
647
827
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
648
828
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -660,95 +840,170 @@ function _ts_param3(paramIndex, decorator) {
660
840
  };
661
841
  }
662
842
  __name(_ts_param3, "_ts_param");
663
- var WebhookController = class {
843
+ var WebhookController = class _WebhookController {
664
844
  static {
665
845
  __name(this, "WebhookController");
666
846
  }
667
847
  capabilityService;
848
+ logger = new Logger4(_WebhookController.name);
668
849
  constructor(capabilityService) {
669
850
  this.capabilityService = capabilityService;
670
851
  }
671
852
  list() {
672
853
  const capabilities = this.capabilityService.listCapabilities();
673
854
  return {
674
- code: 0,
675
- message: "success",
676
- data: capabilities.map((c) => ({
677
- id: c.id,
678
- name: c.name,
679
- description: c.description,
680
- pluginKey: c.pluginKey,
681
- pluginVersion: c.pluginVersion
682
- }))
855
+ status_code: ErrorCodes.SUCCESS,
856
+ data: {
857
+ capabilities: capabilities.map((c) => ({
858
+ id: c.id,
859
+ name: c.name,
860
+ pluginID: c.pluginKey,
861
+ pluginVersion: c.pluginVersion
862
+ }))
863
+ }
683
864
  };
684
865
  }
685
866
  async execute(capabilityId, body) {
686
867
  try {
687
868
  const result = await this.capabilityService.load(capabilityId).call(body.action, body.params);
688
869
  return {
689
- code: 0,
690
- message: "success",
691
- data: result
870
+ status_code: ErrorCodes.SUCCESS,
871
+ data: {
872
+ output: result
873
+ }
692
874
  };
693
875
  } catch (error) {
694
876
  if (error instanceof CapabilityNotFoundError) {
695
877
  throw new HttpException2({
696
- code: 1,
697
- message: error.message,
698
- error: "CAPABILITY_NOT_FOUND"
878
+ status_code: ErrorCodes.CAPABILITY_NOT_FOUND,
879
+ error_msg: `Capability not found: ${capabilityId}`
699
880
  }, HttpStatus2.NOT_FOUND);
700
881
  }
701
882
  if (error instanceof PluginNotFoundError) {
702
883
  throw new HttpException2({
703
- code: 1,
704
- message: error.message,
705
- error: "PLUGIN_NOT_FOUND"
884
+ status_code: ErrorCodes.PLUGIN_NOT_FOUND,
885
+ error_msg: `Plugin not found`
706
886
  }, HttpStatus2.INTERNAL_SERVER_ERROR);
707
887
  }
708
888
  if (error instanceof ActionNotFoundError) {
709
889
  throw new HttpException2({
710
- code: 1,
711
- message: error.message,
712
- error: "ACTION_NOT_FOUND"
890
+ status_code: ErrorCodes.ACTION_NOT_FOUND,
891
+ error_msg: `Action '${body.action}' not found`
713
892
  }, HttpStatus2.BAD_REQUEST);
714
893
  }
715
894
  throw new HttpException2({
716
- code: 1,
717
- message: error instanceof Error ? error.message : String(error),
718
- error: "EXECUTION_ERROR"
895
+ status_code: ErrorCodes.EXECUTION_ERROR,
896
+ error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
719
897
  }, HttpStatus2.INTERNAL_SERVER_ERROR);
720
898
  }
721
899
  }
722
900
  async executeStream(capabilityId, body, res) {
901
+ const startTime = Date.now();
902
+ const loggerContext = {
903
+ capability_id: capabilityId,
904
+ action: body.action
905
+ };
723
906
  res.setHeader("Content-Type", "text/event-stream");
724
907
  res.setHeader("Cache-Control", "no-cache");
725
908
  res.setHeader("Connection", "keep-alive");
726
909
  try {
910
+ this.logger.log(`Executing capability (stream), input: ${stringifyForLog(body.params)}`, loggerContext);
727
911
  const capability = this.capabilityService.load(capabilityId);
728
- const stream = capability.callStream(body.action, body.params);
729
- for await (const chunk of stream) {
730
- res.write(`data: ${JSON.stringify(chunk)}
912
+ const eventStream = capability.callStreamWithEvents(body.action, body.params);
913
+ let pendingChunk = null;
914
+ const allChunks = [];
915
+ for await (const event of eventStream) {
916
+ switch (event.type) {
917
+ case "data": {
918
+ allChunks.push(event.data);
919
+ if (pendingChunk !== null) {
920
+ const response = {
921
+ status_code: ErrorCodes.SUCCESS,
922
+ data: {
923
+ type: "content",
924
+ delta: {
925
+ content: pendingChunk
926
+ }
927
+ }
928
+ };
929
+ res.write(`data: ${JSON.stringify(response)}
930
+
931
+ `);
932
+ }
933
+ pendingChunk = event.data;
934
+ break;
935
+ }
936
+ case "done": {
937
+ if (pendingChunk !== null) {
938
+ const response = {
939
+ status_code: ErrorCodes.SUCCESS,
940
+ data: {
941
+ type: "content",
942
+ delta: {
943
+ content: pendingChunk
944
+ },
945
+ finished: true
946
+ }
947
+ };
948
+ res.write(`data: ${JSON.stringify(response)}
731
949
 
732
950
  `);
951
+ }
952
+ this.logger.log(`Capability (stream) executed successfully, duration: ${Date.now() - startTime}ms, chunks: ${allChunks.length}, result: ${stringifyForLog(allChunks)}`, loggerContext);
953
+ res.end();
954
+ return;
955
+ }
956
+ case "error": {
957
+ const response = {
958
+ status_code: ErrorCodes.SUCCESS,
959
+ data: {
960
+ type: "error",
961
+ error: {
962
+ code: 0,
963
+ message: event.error.message
964
+ }
965
+ }
966
+ };
967
+ res.write(`data: ${JSON.stringify(response)}
968
+
969
+ `);
970
+ res.end();
971
+ return;
972
+ }
973
+ }
733
974
  }
734
- res.write("data: [DONE]\n\n");
735
- } catch (error) {
736
- const message = error instanceof Error ? error.message : String(error);
737
- let errorCode = "EXECUTION_ERROR";
738
- if (error instanceof CapabilityNotFoundError) {
739
- errorCode = "CAPABILITY_NOT_FOUND";
740
- } else if (error instanceof PluginNotFoundError) {
741
- errorCode = "PLUGIN_NOT_FOUND";
742
- } else if (error instanceof ActionNotFoundError) {
743
- errorCode = "ACTION_NOT_FOUND";
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)}
987
+
988
+ `);
744
989
  }
745
- res.write(`data: ${JSON.stringify({
746
- error: message,
747
- code: errorCode
748
- })}
990
+ this.logger.log(`Capability (stream) executed successfully, duration: ${Date.now() - startTime}ms, chunks: ${allChunks.length}, result: ${stringifyForLog(allChunks)}`, loggerContext);
991
+ res.end();
992
+ } catch (error) {
993
+ const errorMsg = error instanceof Error ? error.message : String(error);
994
+ const response = {
995
+ status_code: ErrorCodes.SUCCESS,
996
+ data: {
997
+ type: "error",
998
+ error: {
999
+ code: 0,
1000
+ message: errorMsg
1001
+ }
1002
+ }
1003
+ };
1004
+ res.write(`data: ${JSON.stringify(response)}
749
1005
 
750
1006
  `);
751
- } finally {
752
1007
  res.end();
753
1008
  }
754
1009
  }
@@ -757,7 +1012,7 @@ _ts_decorate5([
757
1012
  Get2("list"),
758
1013
  _ts_metadata3("design:type", Function),
759
1014
  _ts_metadata3("design:paramtypes", []),
760
- _ts_metadata3("design:returntype", typeof ListResponse === "undefined" ? Object : ListResponse)
1015
+ _ts_metadata3("design:returntype", typeof SuccessResponse === "undefined" ? Object : SuccessResponse)
761
1016
  ], WebhookController.prototype, "list", null);
762
1017
  _ts_decorate5([
763
1018
  Post2(":capability_id"),
@@ -793,7 +1048,7 @@ WebhookController = _ts_decorate5([
793
1048
 
794
1049
  // src/capability.module.ts
795
1050
  import { Module } from "@nestjs/common";
796
- import { RequestContextService as RequestContextService2, PLATFORM_HTTP_CLIENT as PLATFORM_HTTP_CLIENT2 } from "@lark-apaas/nestjs-common";
1051
+ import { CommonModule, RequestContextService as RequestContextService2, PLATFORM_HTTP_CLIENT as PLATFORM_HTTP_CLIENT2 } from "@lark-apaas/nestjs-common";
797
1052
  function _ts_decorate6(decorators, target, key, desc) {
798
1053
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
799
1054
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -820,6 +1075,9 @@ var CapabilityModule = class _CapabilityModule {
820
1075
  static forRoot(options) {
821
1076
  return {
822
1077
  module: _CapabilityModule,
1078
+ imports: [
1079
+ CommonModule
1080
+ ],
823
1081
  controllers: getControllers(),
824
1082
  providers: [
825
1083
  {
@@ -854,6 +1112,9 @@ var CapabilityModule = class _CapabilityModule {
854
1112
  };
855
1113
  CapabilityModule = _ts_decorate6([
856
1114
  Module({
1115
+ imports: [
1116
+ CommonModule
1117
+ ],
857
1118
  controllers: getControllers(),
858
1119
  providers: [
859
1120
  CapabilityService,
@@ -871,6 +1132,7 @@ export {
871
1132
  CapabilityNotFoundError,
872
1133
  CapabilityService,
873
1134
  DebugController,
1135
+ ErrorCodes,
874
1136
  PluginLoadError,
875
1137
  PluginLoaderService,
876
1138
  PluginNotFoundError,