@lark-apaas/nestjs-capability 0.1.4-beta.4 → 0.1.4-beta.5

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/README.md CHANGED
@@ -419,8 +419,9 @@ interface PluginInstance {
419
419
 
420
420
  ```typescript
421
421
  interface PluginActionContext {
422
+ pluginKey: string; // 插件标识(如 @official/ai-chat)
422
423
  logger: Logger; // 日志记录器
423
- httpClient: PlatformHttpClient; // HTTP 客户端(平台鉴权)
424
+ platformHttpClient: PlatformHttpClient; // HTTP 客户端(自动携带 x-plugin-key header)
424
425
  userContext: {
425
426
  userId: string; // 用户 ID
426
427
  tenantId: string; // 租户 ID
@@ -430,6 +431,11 @@ interface PluginActionContext {
430
431
  }
431
432
  ```
432
433
 
434
+ **pluginKey 说明:**
435
+ - 每次插件调用都会传入当前插件的标识
436
+ - 插件的 HttpClient 会自动在请求头中携带 `x-plugin-key` header
437
+ - 用于计费追踪、日志关联等场景
438
+
433
439
  **isDebug 说明:**
434
440
  - `DebugController` 调用时 `isDebug = true`
435
441
  - `WebhookController` 或其他调用时 `isDebug = false`
package/dist/index.cjs CHANGED
@@ -63,7 +63,9 @@ var ErrorCodes = {
63
63
  /** 参数验证失败 */
64
64
  PARAMS_VALIDATION_ERROR: "k_ec_cap_004",
65
65
  /** 执行失败 */
66
- EXECUTION_ERROR: "k_ec_cap_005"
66
+ EXECUTION_ERROR: "k_ec_cap_005",
67
+ /** 计费受限 */
68
+ RATE_LIMIT_EXCEEDED: "k_ec_cap_006"
67
69
  };
68
70
 
69
71
  // src/services/template-engine.service.ts
@@ -538,7 +540,7 @@ var CapabilityService = class _CapabilityService {
538
540
  __name(this, "CapabilityService");
539
541
  }
540
542
  requestContextService;
541
- platformHttpClient;
543
+ httpClientFactory;
542
544
  pluginLoaderService;
543
545
  templateEngineService;
544
546
  logger = new import_common3.Logger(_CapabilityService.name);
@@ -548,9 +550,9 @@ var CapabilityService = class _CapabilityService {
548
550
  capabilitiesDir;
549
551
  fileWatcher = null;
550
552
  options = {};
551
- constructor(requestContextService, platformHttpClient, pluginLoaderService, templateEngineService) {
553
+ constructor(requestContextService, httpClientFactory, pluginLoaderService, templateEngineService) {
552
554
  this.requestContextService = requestContextService;
553
- this.platformHttpClient = platformHttpClient;
555
+ this.httpClientFactory = httpClientFactory;
554
556
  this.pluginLoaderService = pluginLoaderService;
555
557
  this.templateEngineService = templateEngineService;
556
558
  const isDev = process.env.NODE_ENV === "development";
@@ -790,7 +792,7 @@ var CapabilityService = class _CapabilityService {
790
792
  if (!pluginInstance.hasAction(actionName)) {
791
793
  throw new ActionNotFoundError(config.pluginKey, actionName);
792
794
  }
793
- const context = this.buildActionContext(contextOverride);
795
+ const context = this.buildActionContext(config.pluginKey, contextOverride);
794
796
  const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
795
797
  this.logger.log("Executing capability (call)", {
796
798
  ...loggerContext,
@@ -840,7 +842,7 @@ var CapabilityService = class _CapabilityService {
840
842
  if (!pluginInstance.hasAction(actionName)) {
841
843
  throw new ActionNotFoundError(config.pluginKey, actionName);
842
844
  }
843
- const context = this.buildActionContext(contextOverride);
845
+ const context = this.buildActionContext(config.pluginKey, contextOverride);
844
846
  const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
845
847
  this.logger.log("Executing capability (stream)", {
846
848
  ...loggerContext,
@@ -890,7 +892,7 @@ var CapabilityService = class _CapabilityService {
890
892
  if (!pluginInstance.hasAction(actionName)) {
891
893
  throw new ActionNotFoundError(config.pluginKey, actionName);
892
894
  }
893
- const context = this.buildActionContext(contextOverride);
895
+ const context = this.buildActionContext(config.pluginKey, contextOverride);
894
896
  const isStream = pluginInstance.isStreamAction?.(actionName) ?? false;
895
897
  this.logger.log("Executing capability (streamWithEvents)", {
896
898
  ...loggerContext,
@@ -956,21 +958,69 @@ var CapabilityService = class _CapabilityService {
956
958
  });
957
959
  yield {
958
960
  type: "error",
959
- error: {
960
- code: "EXECUTION_ERROR",
961
- message: error instanceof Error ? error.message : String(error)
962
- }
961
+ error: this.extractErrorInfo(error)
963
962
  };
964
963
  }
965
964
  }
966
- buildActionContext(override) {
965
+ /**
966
+ * 从错误对象提取错误信息
967
+ * 支持 PluginError 和 RateLimitError
968
+ */
969
+ extractErrorInfo(error) {
970
+ const err = error;
971
+ const code = err?.code ?? "EXECUTION_ERROR";
972
+ const message = err instanceof Error ? err.message : String(err);
973
+ if (code === "RATE_LIMIT_EXCEEDED" && err?.rateLimitCode) {
974
+ return {
975
+ code,
976
+ message,
977
+ rateLimitCode: err.rateLimitCode,
978
+ rateLimitMessage: err.rateLimitMessage
979
+ };
980
+ }
967
981
  return {
982
+ code,
983
+ message
984
+ };
985
+ }
986
+ buildActionContext(pluginKey, override) {
987
+ return {
988
+ pluginKey,
968
989
  logger: this.logger,
969
- platformHttpClient: this.platformHttpClient,
990
+ platformHttpClient: this.createPluginHttpClient(pluginKey),
970
991
  userContext: override?.userContext ?? this.getUserContext(),
971
992
  isDebug: override?.isDebug ?? false
972
993
  };
973
994
  }
995
+ /**
996
+ * 为指定插件创建独立的 HttpClient 实例
997
+ * 自动添加 x-plugin-key header
998
+ */
999
+ createPluginHttpClient(pluginKey) {
1000
+ const client = this.httpClientFactory.create();
1001
+ client.interceptors.request.use((config) => {
1002
+ config.headers = {
1003
+ ...config.headers,
1004
+ "x-plugin-key": pluginKey
1005
+ };
1006
+ return config;
1007
+ });
1008
+ return this.wrapAsProtectedClient(client);
1009
+ }
1010
+ /**
1011
+ * 将 HttpClient 包装为受保护的 PlatformHttpClient
1012
+ * 只暴露请求方法,不暴露 interceptors
1013
+ */
1014
+ wrapAsProtectedClient(client) {
1015
+ return {
1016
+ request: /* @__PURE__ */ __name((config) => client.request(config), "request"),
1017
+ get: /* @__PURE__ */ __name((url, config) => client.get(url, config), "get"),
1018
+ post: /* @__PURE__ */ __name((url, data, config) => client.post(url, data, config), "post"),
1019
+ put: /* @__PURE__ */ __name((url, data, config) => client.put(url, data, config), "put"),
1020
+ patch: /* @__PURE__ */ __name((url, data, config) => client.patch(url, data, config), "patch"),
1021
+ delete: /* @__PURE__ */ __name((url, config) => client.delete(url, config), "delete")
1022
+ };
1023
+ }
974
1024
  getUserContext() {
975
1025
  const ctx = this.requestContextService.getContext();
976
1026
  return {
@@ -982,11 +1032,11 @@ var CapabilityService = class _CapabilityService {
982
1032
  };
983
1033
  CapabilityService = _ts_decorate3([
984
1034
  (0, import_common3.Injectable)(),
985
- _ts_param(1, (0, import_common3.Inject)(import_nestjs_common.PLATFORM_HTTP_CLIENT)),
1035
+ _ts_param(1, (0, import_common3.Inject)(import_nestjs_common.HTTP_CLIENT_FACTORY)),
986
1036
  _ts_metadata("design:type", Function),
987
1037
  _ts_metadata("design:paramtypes", [
988
1038
  typeof import_nestjs_common.RequestContextService === "undefined" ? Object : import_nestjs_common.RequestContextService,
989
- typeof PlatformHttpClient === "undefined" ? Object : PlatformHttpClient,
1039
+ typeof HttpClientFactory === "undefined" ? Object : HttpClientFactory,
990
1040
  typeof PluginLoaderService === "undefined" ? Object : PluginLoaderService,
991
1041
  typeof TemplateEngineService === "undefined" ? Object : TemplateEngineService
992
1042
  ])
@@ -1127,6 +1177,14 @@ var DebugController = class _DebugController {
1127
1177
  error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`
1128
1178
  };
1129
1179
  }
1180
+ const err = error;
1181
+ if (err?.code === "RATE_LIMIT_EXCEEDED" && err?.rateLimitCode) {
1182
+ return {
1183
+ status_code: err.rateLimitCode,
1184
+ error_msg: err.rateLimitMessage || err.message,
1185
+ is_rate_limit_error: true
1186
+ };
1187
+ }
1130
1188
  return {
1131
1189
  status_code: ErrorCodes.EXECUTION_ERROR,
1132
1190
  error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
@@ -1195,13 +1253,15 @@ var DebugController = class _DebugController {
1195
1253
  return;
1196
1254
  }
1197
1255
  case "error": {
1256
+ const isRateLimitError = event.error.code === "RATE_LIMIT_EXCEEDED" && !!event.error.rateLimitCode;
1198
1257
  const response = {
1199
1258
  status_code: ErrorCodes.SUCCESS,
1200
1259
  data: {
1201
1260
  type: "error",
1202
1261
  error: {
1203
- code: 0,
1204
- message: event.error.message
1262
+ code: isRateLimitError ? event.error.rateLimitCode : event.error.code,
1263
+ message: isRateLimitError ? event.error.rateLimitMessage : event.error.message,
1264
+ isRateLimitError: isRateLimitError || void 0
1205
1265
  }
1206
1266
  }
1207
1267
  };
@@ -1228,14 +1288,16 @@ var DebugController = class _DebugController {
1228
1288
  }
1229
1289
  res.end();
1230
1290
  } catch (error) {
1231
- const errorMsg = error instanceof Error ? error.message : String(error);
1291
+ const err = error;
1292
+ const isRateLimitError = err?.code === "RATE_LIMIT_EXCEEDED" && !!err?.rateLimitCode;
1232
1293
  const response = {
1233
1294
  status_code: ErrorCodes.SUCCESS,
1234
1295
  data: {
1235
1296
  type: "error",
1236
1297
  error: {
1237
- code: 0,
1238
- message: errorMsg
1298
+ code: isRateLimitError ? err.rateLimitCode : err?.code ?? "EXECUTION_ERROR",
1299
+ message: isRateLimitError ? err.rateLimitMessage : error instanceof Error ? error.message : String(error),
1300
+ isRateLimitError: isRateLimitError || void 0
1239
1301
  }
1240
1302
  }
1241
1303
  };
@@ -1379,6 +1441,14 @@ var WebhookController = class _WebhookController {
1379
1441
  error_msg: `Action '${error.actionName}' not found in plugin ${error.pluginKey}`
1380
1442
  };
1381
1443
  }
1444
+ const err = error;
1445
+ if (err?.code === "RATE_LIMIT_EXCEEDED" && err?.rateLimitCode) {
1446
+ return {
1447
+ status_code: err.rateLimitCode,
1448
+ error_msg: err.rateLimitMessage || err.message,
1449
+ is_rate_limit_error: true
1450
+ };
1451
+ }
1382
1452
  return {
1383
1453
  status_code: ErrorCodes.EXECUTION_ERROR,
1384
1454
  error_msg: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
@@ -1441,13 +1511,15 @@ var WebhookController = class _WebhookController {
1441
1511
  return;
1442
1512
  }
1443
1513
  case "error": {
1514
+ const isRateLimitError = event.error.code === "RATE_LIMIT_EXCEEDED" && !!event.error.rateLimitCode;
1444
1515
  const response = {
1445
1516
  status_code: ErrorCodes.SUCCESS,
1446
1517
  data: {
1447
1518
  type: "error",
1448
1519
  error: {
1449
- code: 0,
1450
- message: event.error.message
1520
+ code: isRateLimitError ? event.error.rateLimitCode : event.error.code,
1521
+ message: isRateLimitError ? event.error.rateLimitMessage : event.error.message,
1522
+ isRateLimitError: isRateLimitError || void 0
1451
1523
  }
1452
1524
  }
1453
1525
  };
@@ -1474,14 +1546,16 @@ var WebhookController = class _WebhookController {
1474
1546
  }
1475
1547
  res.end();
1476
1548
  } catch (error) {
1477
- const errorMsg = error instanceof Error ? error.message : String(error);
1549
+ const err = error;
1550
+ const isRateLimitError = err?.code === "RATE_LIMIT_EXCEEDED" && !!err?.rateLimitCode;
1478
1551
  const response = {
1479
1552
  status_code: ErrorCodes.SUCCESS,
1480
1553
  data: {
1481
1554
  type: "error",
1482
1555
  error: {
1483
- code: 0,
1484
- message: errorMsg
1556
+ code: isRateLimitError ? err.rateLimitCode : err?.code ?? "EXECUTION_ERROR",
1557
+ message: isRateLimitError ? err.rateLimitMessage : error instanceof Error ? error.message : String(error),
1558
+ isRateLimitError: isRateLimitError || void 0
1485
1559
  }
1486
1560
  }
1487
1561
  };
@@ -1576,8 +1650,8 @@ var CapabilityModule = class _CapabilityModule {
1576
1650
  },
1577
1651
  {
1578
1652
  provide: CapabilityService,
1579
- useFactory: /* @__PURE__ */ __name((requestContextService, httpClient, pluginLoader, templateEngine, moduleOptions) => {
1580
- const service = new CapabilityService(requestContextService, httpClient, pluginLoader, templateEngine);
1653
+ useFactory: /* @__PURE__ */ __name((requestContextService, httpClientFactory, pluginLoader, templateEngine, moduleOptions) => {
1654
+ const service = new CapabilityService(requestContextService, httpClientFactory, pluginLoader, templateEngine);
1581
1655
  if (moduleOptions) {
1582
1656
  service.setOptions(moduleOptions);
1583
1657
  }
@@ -1585,7 +1659,7 @@ var CapabilityModule = class _CapabilityModule {
1585
1659
  }, "useFactory"),
1586
1660
  inject: [
1587
1661
  import_nestjs_common2.RequestContextService,
1588
- import_nestjs_common2.PLATFORM_HTTP_CLIENT,
1662
+ import_nestjs_common2.HTTP_CLIENT_FACTORY,
1589
1663
  PluginLoaderService,
1590
1664
  TemplateEngineService,
1591
1665
  CAPABILITY_OPTIONS